我有一个看起来像这样的集合:
In [127]: df
Out[127]:
ID Date regular_entry
0 1 2014-01-31 12:13:14 True
1 2 2014-02-28 12:13:14 False
2 1 2014-03-31 12:13:14 True
3 1 2014-04-30 12:13:14 True
4 2 2014-05-31 12:13:14 False
5 2 2014-06-30 12:13:14 True
6 3 2014-07-31 12:13:14 False
7 3 2014-08-31 12:13:14 True
8 3 2014-09-30 12:13:14 False
9 1 2014-10-31 12:13:14 True
我需要查找每个组是否有任何行,例如'regular_entry' == False
(如果按'ID'
分组)。
我正在使用pandas.Series.all()
和transform()
来实现这一目标 - 如下所示 - 并且效果很好:
In [134]: df['ever_irregular'] = df.groupby('ID')['regular_entry'].transform(lambda x: False if x.all() else True )
In [135]: df
Out[135]:
ID Date regular_entry ever_irregular
0 1 2014-01-31 12:13:14 True False
1 2 2014-02-28 12:13:14 False True
2 1 2014-03-31 12:13:14 True False
3 1 2014-04-30 12:13:14 True False
4 2 2014-05-31 12:13:14 False True
5 2 2014-06-30 12:13:14 True True
6 3 2014-07-31 12:13:14 False True
7 3 2014-08-31 12:13:14 True True
8 3 2014-09-30 12:13:14 False True
9 1 2014-10-31 12:13:14 True False
现在,我还需要查找每个组的最后一个条目(如果按'ID'
分组并考虑'Date'
的值)是否'regular_entry' == False
我知道我可以像这样获得每组的最后一个条目:
In [138]: df.sort_values(by='Date').groupby('ID').nth(-1)['regular_entry']
Out[138]:
ID
1 True
2 True
3 False
Name: regular_entry, dtype: bool
我现在已经想到我可以尝试加入这两个:
In [152]: df_new = pd.DataFrame(latest_row_regular).rename(columns={'regular_entry':'latest_regular'})
In [155]: pd.merge(df, df_new, left_on='ID', right_index=True).sort_values(by='Date')
Out[155]:
ID Date regular_entry ever_irregular latest_regular
0 1 2014-01-31 12:13:14 True False True
1 2 2014-02-28 12:13:14 False True True
2 1 2014-03-31 12:13:14 True False True
3 1 2014-04-30 12:13:14 True False True
4 2 2014-05-31 12:13:14 False True True
5 2 2014-06-30 12:13:14 True True True
6 3 2014-07-31 12:13:14 False True False
7 3 2014-08-31 12:13:14 True True False
8 3 2014-09-30 12:13:14 False True False
9 1 2014-10-31 12:13:14 True False True
这似乎工作正常,然而,它看起来似乎很长。是否有一些更容易/更快的方法来获取每个组的值(在groupby()
后分组)并直接应用而不是遵循所有中间步骤?
感谢您的帮助!
答案 0 :(得分:2)
df['latest_regular'] = df.groupby('ID')['regular_entry'].transform(lambda x: x.iloc[-1])
print df
ID Date regular_entry latest_regular
0 1 2014-01-31 12:13:14 True True
1 2 2014-02-28 12:13:14 False True
2 1 2014-03-31 12:13:14 True True
3 1 2014-04-30 12:13:14 True True
4 2 2014-05-31 12:13:14 False True
5 2 2014-06-30 12:13:14 True True
6 3 2014-07-31 12:13:14 False False
7 3 2014-08-31 12:13:14 True False
8 3 2014-09-30 12:13:14 False False
9 1 2014-10-31 12:13:14 True True
我认为测试是最好的使用自定义函数print
instaed of lambda:
def f(x):
print x
print x.iloc[-1]
return x.iloc[-1]
df['latest_regular'] = df.groupby('ID')['regular_entry'].transform(f)
print df
测试后使用lambda函数。
答案 1 :(得分:1)
您可以通过以下方式使用相同的.transform
来电:
df['latest_regular'] = (df.groupby('ID')['regular_entry']
.transform(lambda x: x.iloc[-1]))
工作示例:
df['last_regular'] = df.groupby('ID')['regular_entry'].transform(lambda x: x.iloc[-1])
17:41:18 [26]: df
Out[26]:
ID regular_entry last_regular
0 1 True True
1 2 False True
2 1 True True
3 1 True True
4 2 False True
5 2 True True
6 3 False False
7 3 True False
8 3 False False
9 1 True True