如何对含NA值的大型DataFrame每行事件占比进行汇总统计?
处理含NA的DataFrame,计算每行事件占比(分数/百分比形式)
我来帮你搞定这个需求,用Python的pandas就能轻松实现,分步骤给你说明:
1. 准备工作:构造示例数据
首先咱们先把你给出的示例DataFrame构造出来:
import pandas as pd import numpy as np data = { 'user': [100, 200, 300], 'col1': [1, 1, 2], 'col2': [1, 2, 3], 'col3': [2, 3, 3], 'col4': [2, 3, 3], 'col5': [1, np.nan, 2], 'col6': [np.nan, np.nan, np.nan] } df = pd.DataFrame(data)
2. 生成分数形式的汇总结果
按照你的要求,基于每行有效数据的占比计算,步骤如下:
# 提取数值列(排除user标识列) value_cols = df.columns.drop('user') # 计算每行的有效数据总数(排除NA) row_valid_counts = df[value_cols].notna().sum(axis=1) # 统计每行中各事件(1/2/3)的出现次数,未出现的事件补0 event_counts = df[value_cols].apply( lambda x: pd.Series(x.value_counts()).reindex([1, 2, 3], fill_value=0), axis=1 ) event_counts.columns = ['event1', 'event2', 'event3'] # 合并user列并生成分数占比 summarized_df = pd.concat([df['user'], event_counts], axis=1) # 拼接分数字符串,同时把"0/xx"替换为"0" summarized_df[['event1', 'event2', 'event3']] = ( summarized_df[['event1', 'event2', 'event3']].astype(str) + '/' + row_valid_counts.astype(str) ).replace(r'0/\d+', '0', regex=True)
运行后得到的summarized_df就和你期望的结果完全一致:
| user | event1 | event2 | event3 |
|---|---|---|---|
| 100 | 3/5 | 2/5 | 0 |
| 200 | 1/4 | 1/4 | 2/4 |
| 300 | 0 | 2/5 | 3/5 |
3. 生成百分比形式的汇总结果
如果需要用百分比呈现,只需要在计数的基础上计算占比后转成百分比格式:
# 计算数值型的占比(事件次数/有效数据总数) event_ratios = event_counts.div(row_valid_counts, axis=0) # 转成百分比格式,保留1位小数 percent_df = pd.concat( [df['user'], event_ratios.mul(100).round(1).astype(str) + '%'], axis=1 ) percent_df.columns = ['user', 'event1', 'event2', 'event3']
得到的percent_df结果如下:
| user | event1 | event2 | event3 |
|---|---|---|---|
| 100 | 60.0% | 40.0% | 0.0% |
| 200 | 25.0% | 25.0% | 50.0% |
| 300 | 0.0% | 40.0% | 60.0% |
4. 通用化处理(适配任意事件类型)
如果你的数据里事件类型不止1/2/3,可以用下面的代码自动识别所有事件,不需要硬编码:
# 自动获取所有唯一的事件类型并排序 unique_events = sorted(df[value_cols].dropna().unique()) # 统计每行各事件的出现次数 event_counts = df[value_cols].apply( lambda x: pd.Series(x.value_counts()).reindex(unique_events, fill_value=0), axis=1 ) # 自动命名列 event_counts.columns = [f'event{ev}' for ev in unique_events]
这样不管后续新增什么事件类型,代码都能自动适配。
内容的提问来源于stack exchange,提问作者Cina
相关产品推荐
相关产品推荐

