python - 如何计算每行具有动态条件的 Pandas df 元素(=countif)
问题描述
我很想在 Pandas 中做一些相当于 COUNTIF 的事情。我正在努力解决这个问题groupby
,但我很挣扎,因为我的逻辑分组条件是动态的。
假设我有一份客户名单,以及他们访问的日期。我想根据 2 个逻辑条件识别新客户
- 他们必须是同一客户(相同
Guest ID
) - 他们一定是前一天到过那里的
如果满足这两个条件,他们就是回头客。如果不是,它们是新的(因此newby = 1-...
要识别新客户。
我设法通过一个for
循环来做到这一点,但显然性能很糟糕,这与 Pandas 的逻辑相悖。
如何将以下代码包装成比循环更智能的东西?
for i in range (0, len(df)):
newby = 1-np.sum((df["Day"] == df.iloc[i]["Day"]-1) & (df["Guest ID"] == df.iloc[i]["Guest ID"]))
这篇文章没有帮助,因为条件是静态的。我想避免引入“虚拟列”,例如转置df
,因为我将有很多类别(很多客户名称)并且想构建更复杂的逻辑语句。我不想冒着得到许多辅助列的风险
我有以下输入
df
Day Guest ID
0 3230 Tom
1 3230 Peter
2 3231 Tom
3 3232 Peter
4 3232 Peter
并期待这个输出
df
Day Guest ID newby
0 3230 Tom 1
1 3230 Peter 1
2 3231 Tom 0
3 3232 Peter 1
4 3232 Peter 1
请注意,元素3
不一定4
是重复的 - 因为可能有额外的、不同的列(例如它们的顺序)。
解决方案
做:
# ensure the df is sorted by date
df = df.sort_values('Day')
# group by customer and find the diff within each group
df['newby'] = (df.groupby('Guest ID')['Day'].transform('diff').fillna(2) > 1).astype(int)
print(df)
输出
Day Guest ID newby
0 3230 Tom 1
1 3230 Peter 1
2 3231 Tom 0
3 3232 Peter 1
更新
如果每天允许多次访问,您可以执行以下操作:
# only keep unique visits per day
uniques = df.drop_duplicates()
# ensure the df is sorted by date
uniques = uniques.sort_values('Day')
# group by customer and find the diff within each group
uniques['newby'] = (uniques.groupby('Guest ID')['Day'].transform('diff').fillna(2) > 1).astype(int)
# merge the uniques visits back into the original df
res = df.merge(uniques, on=['Day', 'Guest ID'])
print(res)
输出
Day Guest ID newby
0 3230 Tom 1
1 3230 Peter 1
2 3231 Tom 0
3 3232 Peter 1
4 3232 Peter 1
作为替代方案,无需排序或合并,您可以执行以下操作:
lookup = {(day + 1, guest) for day, guest in df[['Day', 'Guest ID']].value_counts().to_dict()}
df['newby'] = (~pd.MultiIndex.from_arrays([df['Day'], df['Guest ID']]).isin(lookup)).astype(int)
print(df)
输出
Day Guest ID newby
0 3230 Tom 1
1 3230 Peter 1
2 3231 Tom 0
3 3232 Peter 1
4 3232 Peter 1
推荐阅读
- pytorch - 在演示中复制语义分析模型
- c# - 如何使用 mysql db、C# 中的存储过程创建 rdlc 报告
- r - 如何使用 get_contrast 获得边际手段
- python - 在循环内连接数据框
- java - 正则表达式使用单词的一部分来获取完整的单词
- reactjs - TS2307:找不到模块“反应引导”
- node.js - docker - 将文件名作为参数传递给 nodejs 应用程序
- javascript - 跟踪相对于元素的光标位置 - javascript / jquery
- python - 如何计算数据框python中特定值之前的出现次数?
- angular - 如何根据 ngModel 值将组件中的“if、else、else if”转换为 switchcase 场景?