基于Pandas实现DataFrame分组行扩展与行列映射需求求助
解决方案:用Pandas矢量化操作实现映射展开
这是一个典型的映射展开需求,用Pandas的merge+explode组合就能高效搞定,完全不需要手动迭代,代码可直接运行验证:
1. 构建示例数据
首先先还原你给出的DF1和DF2:
import pandas as pd # 构建DF1 df1 = pd.DataFrame({ 'A': ['x', 'x', 'x'], 'B': [1, 2, 3] }) # 构建DF2 df2 = pd.DataFrame({ 'Red': ['x', 'x', 'y', 'z'], 'Blue': [10, 11, 12, 13], 'Green': ['car', 'Bus', 'bike', 'cycle'], 'Yellow': ['four', 'six', 'two', 'two'] })
2. 生成映射关系
从DF1中聚合出A列值对应的B列列表,这一步用groupby+agg完成,是矢量化操作:
# 生成A值到B列列表的映射表 mapping = df1.groupby('A')['B'].agg(list).reset_index()
得到的mapping如下:
| A | B |
|---|---|
| x | [1, 2, 3] |
3. 合并+展开得到DF3
将DF2和映射表做左连接,然后替换目标列并展开列表:
# 左连接DF2和映射表,关联键是DF2的Red列和映射表的A列 df3 = df2.merge(mapping, left_on='Red', right_on='A', how='left') # 替换Red列:有映射的行用B列的列表,无映射的行保留原Red值 df3['Red'] = df3['B'].fillna(df3['Red']) # 展开列表,把每个列表元素拆成单独行 df3 = df3.explode('Red').drop(columns=['A', 'B']) # 可选:重置索引 df3 = df3.reset_index(drop=True)
最终结果
运行后得到的df3就是你想要的DF3:
| Red | Blue | Green | Yellow |
|---|---|---|---|
| 1 | 10 | car | four |
| 2 | 10 | car | four |
| 3 | 10 | car | four |
| 1 | 11 | Bus | six |
| 2 | 11 | Bus | six |
| 3 | 11 | Bus | six |
| y | 12 | bike | two |
| z | 13 | cycle | two |
优势说明
这个方案全程用Pandas内置的矢量化操作,没有任何循环迭代,效率很高。而且如果DF1里有多个不同的A值(比如除了x还有其他需要替换的),这个代码也能自动适配,不需要额外修改。
内容的提问来源于stack exchange,提问作者D83
相关产品推荐
相关产品推荐

