如何按ID和日期连续统计DataFrame输入元素频次并重命名列?
这个需求的核心是按ID分组后,对每个元素追踪连续出现的次数——只要当前行没出现该元素,计数就重置为0;连续出现的话就累加。我用pandas来实现的话,步骤拆解下来很清晰:
1. 先搞定示例数据(如果你的df已经存在,这步直接跳过)
先把你给的样例数据构造出来,方便后续验证:
import pandas as pd data = { 'ID': [1, 1, 2, 2], 'Date': ['1-Nov', '2-NOV', '3-NOV', '4-NOV'], 'Input': ['A,B', 'A', 'A,B,C', 'B,D'] } df = pd.DataFrame(data)
2. 把Input转成元素的"出现标记"
我们需要先把逗号分隔的Input列,转换成每行对应元素是否出现的标记(1表示出现,0表示没出现),pandas的str.get_dummies方法能一键搞定这个:
dummies = df['Input'].str.get_dummies(sep=',')
这时候dummies是一个只有0和1的DataFrame,列就是A、B、C、D,对应每个元素在该行是否存在。
3. 按ID分组计算连续计数(最关键的一步)
这一步要实现的逻辑是:对同一个ID下的每个元素,只要当前行没出现它,计数直接归0;如果连续出现,就从1开始往上加。
我这里用了几个小技巧组合:
col != col.shift():判断当前行和上一行的元素出现状态有没有变化,变化的地方会生成一个标记点groupby((col != col.shift()).cumsum()):根据这些标记点,把连续的相同状态(连续出现/连续不出现)分成不同的组cumcount() + 1:在每个组内计算连续的次数,加1是因为cumcount默认从0开始计数- 最后乘以原列的0/1值,这样就能确保没出现元素的行,计数直接变成0
代码写出来是这样:
counts = dummies.groupby(df['ID']).apply( lambda x: x.apply( lambda col: col * (col.groupby((col != col.shift()).cumsum()).cumcount() + 1) ) ).reset_index(drop=True)
4. 重命名列并合并结果
把计数列的名字改成你要的X.A、X.B格式,然后和原DataFrame合并到一起:
# 重命名计数列 counts.columns = [f'X.{col}' for col in counts.columns] # 合并原数据和计数结果 result = pd.concat([df, counts], axis=1)
最终输出结果
打印result就能得到你期望的表格:
ID Date Input X.A X.B X.C X.D 0 1 1-Nov A,B 1 1 0 0 1 1 2-NOV A 2 0 0 0 2 2 3-NOV A,B,C 1 1 1 0 3 2 4-NOV B,D 0 2 0 1
内容的提问来源于stack exchange,提问作者SS25
相关产品推荐
相关产品推荐

