在Pandas中根据另一列值将多列熔转为单列的问题
解决根据B列匹配列名提取值的问题
我明白你的需求啦——就是要根据每行B列的数值,找到对应列名的列,然后取出那个位置的值,最终生成指定结构的DataFrame。下面给你几个可行的实现方案,包括你尝试过的melt方法的正确用法,还有更高效的专属方法:
首先先回顾下你的原始数据:
import pandas as pd import numpy as np # 你的原始DataFrame df = pd.DataFrame([['alpha',1,2,3], ['beta', 4,5,6], ['gamma',4,8,9]], columns=['A','B', 1, 4])
对应的表格结构:
| A | B | 1 | 4 |
|---|---|---|---|
| alpha | 1 | 2 | 3 |
| beta | 4 | 5 | 6 |
| gamma | 4 | 8 | 9 |
方法1:用df.lookup()(最直接的专属方法)
lookup就是专门用来根据行索引和列索引匹配取值的工具,非常适合你的场景:
# 构造结果DataFrame result = pd.DataFrame({ 'A': df['A'], 'B': df['B'], 'value': df.lookup(df.index, df['B']) })
运行后就能得到你想要的结果:
| A | B | value |
|---|---|---|
| alpha | 1 | 2 |
| beta | 4 | 6 |
| gamma | 4 | 9 |
方法2:用np.take_along_axis()(未来兼容的推荐方法)
因为lookup在pandas的未来版本中有被弃用的计划,所以可以用更稳健的numpy方法实现:
# 提取所有需要匹配的数字列(这里是列名1和4的列) num_columns = df.columns[2:] # 或者直接写[1, 4]更明确 # 找到每行B值在num_columns中的位置索引 col_positions = np.where(num_columns == df['B'].values[:, None])[1] # 根据位置提取对应的值 extracted_values = np.take_along_axis(df[num_columns].values, col_positions[:, None], axis=1).flatten() # 组装结果 result = pd.DataFrame({ 'A': df['A'], 'B': df['B'], 'value': extracted_values })
方法3:用melt实现(补上你没完成的步骤)
你之前尝试melt没成功,应该是少了过滤匹配行的步骤,完整流程如下:
# 把宽表转长表,保留A、B列作为标识列 melted_df = df.melt(id_vars=['A', 'B'], var_name='match_col', value_name='value') # 过滤出match_col和B列值相等的行,然后删除冗余列 result = melted_df[melted_df['match_col'] == melted_df['B']].drop('match_col', axis=1)
这个方法逻辑更直观,适合需要先查看所有可能匹配关系的场景。
这三种方法都能得到你想要的结果,你可以根据自己的习惯和pandas版本选择合适的方式~
内容的提问来源于stack exchange,提问作者bazinga
相关产品推荐
相关产品推荐

