pandas:根据行中的值与列添加的date比较

我有一些类似格式的excel文件:

|name| email| cat1| cat2| cat3 smith email 01JAN2016 01JAN2014 01JAN2015 

前两列包含string(名称和电子邮件地址),而以下每列包含每个人完成cat(x)中的每个项目的date。

我想运行一个比较current_date,添加一个新的列“状态”,将有一个值'兼容'或'拖延'的基础上是否有任何date在当前date之后,然后输出新的dataframe到Excel电子表格。

我最初的尝试让我很容易地过滤“较旧”的date,但是,当我尝试添加一个使用条件的列时,一切都开始中断:

 import pandas as pd import numpy as np import datetime current_date = datetime.datetime.now() writer = pd.ExcelWriter('pd_output.xlsx', engine='xlsxwriter', datetime_format= 'mmm d yyy') df = pd.read_excel(tracker,'Sheet1') print(df.values) # Displays dates as 'Timestamp('2016-01-01 00:00:00') any value which is < current_date displays as 'True' else 'False' print(df < current_date) # removes dates that are not older than current_date but does not delete column, ie someone with no old dates will still show up with column 3+ being blank # a couple version of what I have been trying - unsuccessfully df['Status'] = np.where(df[df < current_date], 'delinquent', 'compliant' # error: 'wrong number of items passed df['Status'] = np.where(df == 'True', 'delinquent', 'compliant' # error: 'str' obj has no attr 'view' df['Status' = df.Set.map(lambda x: 'delinquent' if 'True' in df else 'compliant' # from another post - error 'no attr 'Set' or 'map' # send to output excel df.to_excel(writer,sheet_name='Sheet1') 

我想有一个输出,显示行的'状态'列另外显示行内有'违规date' – 用'合规'或'拖欠'引爆。 我觉得我正在做我的比较不正确(使用True而不是另一个地方),但似乎无法做到正确。

当您想要根据一个或多个其他列的值创build新列时,通常使用其中一个apply函数。 当函数是多列时,就像这里的情况一样,使用DataFrame.apply 。 下面是我认为你想要做的一个近似:

 df['Status'] = df.apply ( lambda df : ( 'delinquent' if any (df[i] < current_date for i in ("cat1","cat2","cat3")) else 'compliant' ) , axis = 1 ) 

(仅供参考,我从你的逻辑中认为“拖欠”意味着date在当前date之前,如果我错了,请将上面的< symbol >倒过来。)

让我们解开这一点。 apply将vector化函数应用于整个数据框。 我们需要应用整个数据框,因为我们正在查看多个列; 不久,我们将指定哪些。 该函数是我们定义的lambdaaxis = 1参数告诉apply将lambda应用到每一行(这不是默认值,默认是axis = 0 ,这适用于每一列 – 不是我们想要的)。 lambda本身按名称查看所有3个date列,如果其中任何一个在当前date之前返回“拖欠”。 为了避免写if df["cat1"] < current_date or df["cat2"] < current_date or df["cat3"] < current_date等等的苦差事,我在里面使用了any()

请注意,所有这一切取决于你的3date列是types的datetime – 我假设他们是。

如果你只有一个date列,比如说“cat1”,那么你可以在这一列上使用稍微简单Series.apply

 df['Status'] = df['cat1'].apply ( lambda x : 'delinquent' if x < current_date else 'compliant' ) 

这样做的基本原理是简单的function和缺lessaxis参数。 因此,一般情况下,人们在应用一列的函数时使用Series.apply ,如果函数的列数多于一列,则使用Series.apply