如何计算列值出现频次?排查Pandas客户交易统计代码异常
问题排查与处理方案
需求
计算一列中相同值的出现次数及另一列中对应值的出现次数。
样本DataFrame
data = { 'CUSTOMER_ID': [31381, 7180, 132, 334, 11, 78], 'TX_DATE': ['2023-06-01', '2024-03-08', '2023-03-07', '2003-03-01', '2020-03-02', '2023-03-08'], 'TX_WEEK': [1, 11, 14, 17, 18, 19] } df_transactions = pd.DataFrame(data)
当前代码
# previous day df_transactions['CUSTOMER_TOTAL_1D'] = df_transactions.groupby('CUSTOMER_ID')['DAILY_COUNTS'].shift() # previous week df_transactions['CUSTOMER_TOTAL_1W'] = df_transactions.groupby('CUSTOMER_ID')['WEEKLY_COUNTS'].shift() df_transactions.drop(columns=['DAILY_COUNTS',"WEEKLY_COUNTS"], inplace=True) df_transactions
问题现象
代码生成结果大多为0,与实际大数据集的预期不符,需排查逻辑问题并明确后续处理方向。
核心逻辑问题分析
- 缺失关键统计步骤:代码直接对
DAILY_COUNTS和WEEKLY_COUNTS执行shift操作,但这两列既未在样本数据中定义,也没有前置统计流程生成。若这两列实际是默认0值或NaN被填充为0,必然导致结果大量为0。 - shift操作逻辑偏差:即便上述列存在,
groupby('CUSTOMER_ID').shift()的作用是取同一客户的上一条记录值,而非统计相同值的出现次数。若客户仅存在一条记录,shift后会得到NaN,后续若被填充为0,也会造成大量0值结果。 - 需求与代码目标不匹配:需求是统计“相同值的出现次数”,但当前代码逻辑是获取客户前一天/前一周的交易计数,二者方向完全不符。
后续处理方向
1. 明确统计目标
先厘清具体需求:
- 是统计每个
CUSTOMER_ID在全数据集的总出现次数? - 还是每个客户在对应日期/周的交易次数?
- 或是每个客户前一天/前一周的交易次数(当前代码的疑似目标)?
2. 针对“获取客户前一期交易计数”的修正方案
若目标是获取客户前一天/前一周的交易次数,需补全统计流程:
# 1. 计算每个客户每日交易次数 df_transactions['DAILY_COUNTS'] = df_transactions.groupby(['CUSTOMER_ID', 'TX_DATE'])['TX_DATE'].transform('count') # 2. 计算每个客户每周交易次数 df_transactions['WEEKLY_COUNTS'] = df_transactions.groupby(['CUSTOMER_ID', 'TX_WEEK'])['TX_WEEK'].transform('count') # 3. 按客户+日期排序后,取前一天的交易次数(NaN填充为0) df_transactions = df_transactions.sort_values(['CUSTOMER_ID', 'TX_DATE']) df_transactions['CUSTOMER_TOTAL_1D'] = df_transactions.groupby('CUSTOMER_ID')['DAILY_COUNTS'].shift().fillna(0) # 4. 按客户+周排序后,取前一周的交易次数(NaN填充为0) df_transactions = df_transactions.sort_values(['CUSTOMER_ID', 'TX_WEEK']) df_transactions['CUSTOMER_TOTAL_1W'] = df_transactions.groupby('CUSTOMER_ID')['WEEKLY_COUNTS'].shift().fillna(0) # 5. 按需删除中间列 df_transactions.drop(columns=['DAILY_COUNTS', 'WEEKLY_COUNTS'], inplace=True)
3. 针对“统计相同值出现次数”的实现方案
若需求是统计列中相同值的出现次数,可采用以下方式:
# 统计每个CUSTOMER_ID在全数据集的出现次数 df_transactions['CUSTOMER_OCCURRENCE'] = df_transactions['CUSTOMER_ID'].map(df_transactions['CUSTOMER_ID'].value_counts()) # 统计每个TX_DATE对应的交易记录数(即当日总交易次数) df_transactions['DATE_TX_COUNT'] = df_transactions['TX_DATE'].map(df_transactions['TX_DATE'].value_counts())
内容的提问来源于stack exchange,提问作者sarhh
相关产品推荐
相关产品推荐

