如何用Pandas基于分类列Bins合并多列为统一的Color、Size列?
解决Pandas中按分类合并列的问题
问题描述
现有如下结构的Pandas DataFrame:
| Bins | A_Color | B_Color | A_Size | B_Size |
|---|---|---|---|---|
| A | 'Red' | 50 | ||
| B | 'Blue' | 60 |
需要将按分类(A、B等)拆分的Color和Size列,合并为统一的Color和Size列,最终得到:
| Bins | Color | Size |
|---|---|---|
| A | 'Red' | 50 |
| B | 'Blue' | 60 |
尝试了以下代码,但生成的['Color', 'Size']列全为NaN值:
bins = ['A', 'B', 'C', 'D', 'E'] for b in bins: df.loc[df['Bins'] == b, ['Color', 'Size']] = \ df.loc[df['Bins'] == b, [f'{b}_Color', f'{b}_Size']]
实际数据包含约10万行、300+列,需要高效的解决方案。
错误原因
循环赋值存在两个核心问题:
- Pandas赋值时会严格匹配索引,当子DataFrame的索引与原DataFrame索引不完全对齐时,会直接导致赋值失败生成NaN;
- 循环遍历每个分类的操作,对于10万行的大数据来说效率极低,违背了Pandas向量化操作的最优实践。
高效解决方案
方案1:使用lookup方法(最优,适配大数据)
lookup是Pandas专门用于按行匹配列名提取值的方法,完全向量化操作,效率极高:
# 根据Bins值匹配对应Color列并提取值 df['Color'] = df.lookup(df.index, df['Bins'] + '_Color') # 同理提取Size值 df['Size'] = df.lookup(df.index, df['Bins'] + '_Size') # 保留最终需要的列 df = df[['Bins', 'Color', 'Size']]
方案2:重塑数据(通用型,支持多属性扩展)
如果后续有更多类似的属性列(如X_Weight、Y_Weight等),可以用melt+pivot的方式一次性处理所有属性:
# 将宽表转为长表,拆分列名为「分类」和「属性」两部分 melted = df.melt(id_vars='Bins', var_name='Category_Attr', value_name='Value') melted[['Category', 'Attr']] = melted['Category_Attr'].str.split('_', expand=True) # 只保留与Bins分类匹配的行 melted = melted[melted['Category'] == melted['Bins']] # 转回宽表得到目标结构 result = melted.pivot(index='Bins', columns='Attr', values='Value').reset_index() result.columns.name = None # 移除列名的层级标签
内容的提问来源于stack exchange,提问作者Kam
相关产品推荐
相关产品推荐

