[英]How to convert group.iterrows() loop result to dataframe in Pandas
考虑以下数据:
df['rank']=df.groupby('Contact').cumcount()
df.set_index('rank', inplace=True, drop=True)
df
接触 | 新的 | 老的 | 日期新 | 日期旧 | 修改日期 | 用户 | 秩 |
---|---|---|---|---|---|---|---|
0 | 玛丽 | 错误的 | 真的 | 2021-01-12 11:00:00 | 钠盐 | 2021-01-12 12:48:00 | 系统 |
1 | 玛丽 | 真的 | 错误的 | 钠盐 | 2021-01-12 11:00:00 | 2021-01-12 12:47:00 | 抢 |
2 | 玛丽 | 错误的 | 真的 | 2021-01-12 11:00:00 | 钠盐 | 2021-01-12 12:45:00 | 系统 |
3 | 玛丽 | 真的 | 错误的 | 钠盐 | 2021-11-29 11:00:00 | 2021-01-12 12:44:00 | 抢 |
0 | 约翰 | 真的 | 错误的 | 钠盐 | 2021-12-10 11:00:00 | 2021-12-10 16:15:00 | 蒂娜 |
1 | 约翰 | 错误的 | 真的 | 2021-12-10 11:00:00 | 钠盐 | 2021-12-10 15:30:00 | 系统 |
2 | 约翰 | 真的 | 错误的 | 钠盐 | 2021-12-10 11:00:00 | 2021-12-10 15:29:00 | 莉娜 |
3 | 约翰 | 错误的 | 真的 | 2021-12-10 11:00:00 | 钠盐 | 2021-12-10 12:37:00 | 系统 |
如何将以下结果转换为 dataframe? df
是pandas.core.frame.DataFrame
和grp
是pandas.core.groupby.generic.DataFrameGroupBy
。
grp = df.groupby('Contact')
for name,group in grp:
for i,row in group.iterrows():
if i < len(group)-1:
if (group.loc[i,'Old'] == group.loc[i+1,'New']):
if group.loc[i,'User'] == 'sys':
if group.loc[i+1,'User'] !='sys':
group.loc[i,'Overwritten']= True
else:
group.loc[i,'Overwritten']= False
else:
group.loc[i,'Overwritten']= False
else:
group.loc[i,'Overwritten']= False
print(group)
上述解决方案可能不是最好的方法,也许我可以使用shift
function。 但我想知道如何将循环中的groupby
结果作为数据框获取,以便进行更多过滤/分析。 我还是 Pandas 的新手。 谢谢。
通过按联系人排序并使用shift
列计算 boolean 列Overwritten来避免groupby
和iterrows
。 实际上,您可以将所有if
展平为单个逻辑检查:
calc_df = (
df.sort_values('Contact') # SORT BY GROUPING VARIABLE
.reset_index(drop=True) # RESET INDEX FOR SHIFT COLS
.assign( # ADD SHIFT HELPER COLUMNS
Contact_ = lambda df: df['Contact'].shift(-1),
New_ = lambda df: df['New'].shift(-1),
User_ = lambda df: df['User'].shift(-1),
Overwritten = lambda df: ( # CALCULATE BOOLEAN COLUMN
(df['Contact'] == df['Contact_']) &
(df['Old'] == df['New_']) &
(df['User'] == 'sys') &
(df['User_'] != 'sys')
)
)
)
calc_df
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.