我有一个包含两列的pandas数据框,第一个只有一个日期('action_date'),第二个有一个日期列表('verification_date')。我正在尝试计算'action_date'中的日期与相应'verification_date'列中列表中的每个日期之间的时差,然后使用在verification_date中具有相同差异的日期数填充df新列超过或低于360天。
这是我的代码:
df = pd.DataFrame()
df['action_date'] = ['2017-01-01', '2017-01-01', '2017-01-03']
df['action_date'] = pd.to_datetime(df['action_date'], format="%Y-%m-%d")
df['verification_date'] = ['2016-01-01', '2015-01-08', '2017-01-01']
df['verification_date'] = pd.to_datetime(df['verification_date'], format="%Y-%m-%d")
df['user_name'] = ['abc', 'wdt', 'sdf']
df.index = df.action_date
df = df.groupby(pd.TimeGrouper(freq='2D'))['verification_date'].apply(list).reset_index()
def make_columns(df):
df = df
for i in range(len(df)):
over_360 = []
under_360 = []
for w in [(df['action_date'][i]-x).days for x in df['verification_date'][i]]:
if w > 360:
over_360.append(w)
else:
under_360.append(w)
df['over_360'] = len(over_360)
df['under_360'] = len(under_360)
return df
make_columns(df)
这种方式有效除了df每行有相同的值,因为日期不同,所以不是这样。例如,在数据框的第一行中,action_date与verification_date列中列表中的两个项之间存在超过360天的差异,因此over_360列应填充为2.但是,它是空的相反,under_360列填充为1,这仅对'action_date'中的第二行准确。
我有一种感觉,我只是弄乱了循环,但我真的被卡住了。谢谢大家的帮助!
答案 0 :(得分:1)
您的问题是您始终使用以下行的最后一次计算值更新整个列:
df['over_360'] = len(over_360)
df['under_360'] = len(under_360)
您想要做的是相应地设置每个行计算的值,您可以通过将以上行替换为以下行来执行此操作:
df.set_value(i,'over_360',len(over_360))
df.set_value(i,'under_360',len(under_360))
它的作用是,它在行i
和列over_360
或under_360
中设置一个值。
您可以了解有关它的更多信息here。
如果您不喜欢使用set_values
,也可以使用:
df.ix[i,'over_360'] = len(over_360)
df.ix[i,'under_360'] = len(under_360)
您可以查看dataframe.ix here。
答案 1 :(得分:1)
你可能想试试这个:
df['over_360'] = df.apply(lambda x: sum([((x['action_date'] - i).days >360) for i in x['verification_date']]) , axis=1)
df['under_360'] = df.apply(lambda x: sum([((x['action_date'] - i).days <360) for i in x['verification_date']]) , axis=1)
我相信它应该快一点。 如果== 360,您没有指定要执行的操作,因此您只需更改&gt;或者&lt;进入&gt; =或&lt; =。