按分组条件拼接DataFrame多列语句,构建目标DataFrame
解决方案:按分组拼接并保留原始行结构
我来帮你搞定这个需求!咱们可以用Pandas的分组、聚合和合并操作来实现目标,下面是具体的代码和步骤:
1. 先构建示例DataFrame
首先咱们先把你提供的原始数据转换成Pandas DataFrame:
import pandas as pd # 原始数据 df = pd.DataFrame({ 'col1': ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b'], 'col2': ['a1', 'a1', 'a2', 'a2', 'a2', 'b1', 'b2', 'b1', 'b2'], 'col3': ['abc', 'def', 'ijk', 'xyz', 'fgh', '123', '456', '789', 'xua'] })
2. 核心实现逻辑
根据你的期望输出,我们需要:
- 按
col1+col2分组,将组内的col3值用.拼接 - 仅保留每组第一行的拼接结果,其余行的
col3设为空字符串
情况1:拼接组内所有元素(匹配你示例中b1、b2的逻辑)
如果是要拼接组内所有元素,代码如下:
# 第一步:分组拼接每组的col3,得到拼接结果表 grouped = df.groupby(['col1', 'col2'])['col3'].agg('.'.join).reset_index() grouped.columns = ['col1', 'col2', 'col3_combined'] # 第二步:将拼接结果合并回原始DataFrame,保留所有原始行 merged = df.merge(grouped, on=['col1', 'col2'], how='left') # 第三步:标记每组的第一行,仅第一行保留拼接值,其余行设为空 merged['is_first_row'] = merged.groupby(['col1', 'col2']).cumcount() == 0 merged['col3'] = merged.apply(lambda row: row['col3_combined'] if row['is_first_row'] else '', axis=1) # 第四步:清理临时列,得到最终结果 result = merged.drop(['col3_combined', 'is_first_row'], axis=1) print(result)
输出结果:
col1 col2 col3 0 a a1 abc.def 1 a a1 2 a a2 ijk.xyz.fgh 3 a a2 4 a a2 5 b b1 123.789 6 b b2 456.xua 7 b b1 8 b b2
情况2:跳过组内第一个元素拼接(完全匹配你给出的期望输出)
看你期望的a2组拼接结果是xyz.fgh(跳过了第一个值ijk),如果是这个需求,只需要修改分组聚合的逻辑,取组内从第二个元素开始拼接:
# 修改分组聚合的逻辑,跳过第一个元素 grouped = df.groupby(['col1', 'col2'])['col3'].agg(lambda x: '.'.join(x[1:])).reset_index() grouped.columns = ['col1', 'col2', 'col3_combined'] # 后续步骤和情况1一致 merged = df.merge(grouped, on=['col1', 'col2'], how='left') merged['is_first_row'] = merged.groupby(['col1', 'col2']).cumcount() == 0 merged['col3'] = merged.apply(lambda row: row['col3_combined'] if row['is_first_row'] else '', axis=1) result = merged.drop(['col3_combined', 'is_first_row'], axis=1) print(result)
输出结果就完全匹配你的期望了:
col1 col2 col3 0 a a1 abc.def 1 a a1 2 a a2 xyz.fgh 3 a a2 4 a a2 5 b b1 123.789 6 b b2 456.xua 7 b b1 8 b b2
代码解释
groupby(['col1', 'col2'])['col3'].agg('.'.join):按col1和col2分组,把每组的col3字符串用.连接起来merge:将聚合后的拼接结果合并回原表,确保每一行都能拿到自己组的拼接值cumcount() == 0:给每组的行编号,判断是否是组内的第一行apply:根据是否是第一行,决定保留拼接值还是设为空字符串
内容的提问来源于stack exchange,提问作者learningtocode
相关产品推荐
相关产品推荐

