如何在Pandas中按自定义列表处理数据框并实现求和、平均与筛选
问题描述
给定如下Pandas DataFrame df:
TxnId TxnDate TxnCount 100 2023-02-01 2 500 2023-02-01 1 400 2023-02-01 4 100 2023-02-02 3 500 2023-02-02 5 100 2023-02-03 3 500 2023-02-03 5 400 2023-02-03 2
同时有自定义列表:
datelist = [datetime.date(2023,02,03), datetime.date(2023,02,02)] txnlist = [400,500]
需要实现以下逻辑:
- 对
txnlist中的每个TxnId,累加datelist对应日期的TxnCount - 计算每个筛选后
TxnId在datelist日期范围内的TxnCount平均值(缺失日期按0计算) - 将平均值大于3的条目(格式为
[TxnId, 累加值])加入breachList
预期结果:
累加后的结果:
TxnId TxnCount 400 2 500 10
平均值计算:
- TxnId 400:(2+0)/2 = 1
- TxnId 500:(5+5)/2 = 5
最终breachList = [[500,10]]
实现步骤
1. 预处理数据:统一日期格式
先确保df中的TxnDate列与datelist元素类型一致(均为date类型):
import pandas as pd import datetime # 转换日期列格式 df['TxnDate'] = pd.to_datetime(df['TxnDate']).dt.date
2. 生成完整日期-TxnId组合,填充缺失值
为了处理缺失日期(比如TxnId 400在2023-02-02无数据),需要生成txnlist和datelist的笛卡尔积,再与原数据合并,缺失的TxnCount填充为0:
# 生成笛卡尔积的索引并转为DataFrame full_index = pd.MultiIndex.from_product([txnlist, datelist], names=['TxnId', 'TxnDate']) full_df = pd.DataFrame(index=full_index).reset_index() # 合并原数据,填充缺失值 merged_df = pd.merge(full_df, df, on=['TxnId', 'TxnDate'], how='left').fillna({'TxnCount': 0})
3. 计算累加值与平均值
按TxnId分组,统计每个Id的TxnCount总和(累加值)和平均值:
result_df = merged_df.groupby('TxnId').agg( TxnCount_Sum=('TxnCount', 'sum'), TxnCount_Avg=('TxnCount', 'mean') ).reset_index()
4. 生成breachList
筛选出平均值大于3的条目,转换为要求的列表格式:
breachList = result_df[result_df['TxnCount_Avg'] > 3][['TxnId', 'TxnCount_Sum']].values.tolist()
完整可运行代码
import pandas as pd import datetime # 构造示例DataFrame data = { 'TxnId': [100, 500, 400, 100, 500, 100, 500, 400], 'TxnDate': ['2023-02-01', '2023-02-01', '2023-02-01', '2023-02-02', '2023-02-02', '2023-02-03', '2023-02-03', '2023-02-03'], 'TxnCount': [2, 1, 4, 3, 5, 3, 5, 2] } df = pd.DataFrame(data) # 自定义列表 datelist = [datetime.date(2023,2,3), datetime.date(2023,2,2)] txnlist = [400,500] # 1. 转换日期格式 df['TxnDate'] = pd.to_datetime(df['TxnDate']).dt.date # 2. 生成完整组合并填充缺失值 full_index = pd.MultiIndex.from_product([txnlist, datelist], names=['TxnId', 'TxnDate']) full_df = pd.DataFrame(index=full_index).reset_index() merged_df = pd.merge(full_df, df, on=['TxnId', 'TxnDate'], how='left').fillna({'TxnCount': 0}) # 3. 计算总和与平均值 result_df = merged_df.groupby('TxnId').agg( TxnCount_Sum=('TxnCount', 'sum'), TxnCount_Avg=('TxnCount', 'mean') ).reset_index() # 4. 生成breachList breachList = result_df[result_df['TxnCount_Avg'] > 3][['TxnId', 'TxnCount_Sum']].values.tolist() # 输出结果 print("累加结果:") print(result_df[['TxnId', 'TxnCount_Sum']].rename(columns={'TxnCount_Sum': 'TxnCount'})) print("\nbreachList:") print(breachList)
运行后输出与预期完全一致:
累加结果: TxnId TxnCount 0 400 2 1 500 10 breachList: [[500, 10]]
内容的提问来源于stack exchange,提问作者KurinchiMalar
相关产品推荐
相关产品推荐

