如何对含重复项的DataFrame分组,将issuer设为列并添加median列?
实现DataFrame分组透视并添加中位数列
问题背景
现有如下结构的DataFrame:
date name issuer rate 2022-01-01 SPY A 0.3 2022-01-01 SPY B 0.2 2022-01-01 MSFT A 0.2 2022-01-01 MSFT B 0.1 2022-01-02 SPY A 0.2 2022-01-02 SPY B 0.1 2022-01-02 SPY C 0.2 2022-01-02 SPY D 0.2 2022-01-02 MSFT A 0.2 2022-01-02 MSFT B 0.4 2022-01-02 MSFT C 0.5 2022-01-02 MSFT D 0.4
需要将其转换为以date和name为多级行索引,issuer为列名,并添加median列存储每行非空值中位数的格式,目标结果如下:
A B C D median date name 2022-01-01 SPY 0.3 0.2 0.25 MSFT 0.2 0.1 0.15 2022-01-02 SPY 0.2 0.1 0.2 0.2 0.2 MSFT 0.2 0.4 0.5 0.4 0.4
最优实现方案
使用pandas的pivot_table函数可以完美解决这个问题,它既支持将issuer转为列名,又能处理潜在的重复项(通过聚合函数),步骤如下:
1. 透视数据
通过pivot_table将date和name设为行索引,issuer设为列,rate为对应值。由于示例中每个(date, name, issuer)组合唯一,使用aggfunc='first'保留原始值即可:
import pandas as pd # 假设df已加载完成 pivoted_df = df.pivot_table( index=['date', 'name'], columns='issuer', values='rate', aggfunc='first' )
2. 添加中位数列
对每行的非空值计算中位数,添加为median列:
pivoted_df['median'] = pivoted_df.apply(lambda row: row.dropna().median(), axis=1)
3. 优化显示格式(可选)
如果希望空值显示为空白而非NaN,可以单独处理非中位数列的空值:
# 保留中位数的数值类型,仅将其他列的空值替换为空白 for col in pivoted_df.columns[:-1]: pivoted_df[col] = pivoted_df[col].fillna('')
最终结果
执行上述代码后,pivoted_df的结构和数值将与目标格式完全一致。
为什么不用groupby或pivot?
pivot要求行索引与列的组合必须唯一,若数据存在重复项会直接报错;而pivot_table通过聚合函数(如first/mean)自动处理重复项,容错性更强。groupby本身仅能按指定键分组聚合,无法直接将issuer转为列名,需要额外配合unstack操作,步骤更繁琐,不如pivot_table一步到位。
内容的提问来源于stack exchange,提问作者MathMan 99
相关产品推荐
相关产品推荐

