如何基于指定列的相同值合并Python DataFrame多行数据
问题:合并DataFrame中同plate_id的多行并生成新列
我在Python中处理一个DataFrame,需要将plate_id相同的多行合并为一行,同时生成ZPE_response、HPE_response、ZPE_response_stdev、HPE_response_stdev这类新列。
示例DataFrame如下:
import pandas as pd df=pd.DataFrame({'drug1' : {0 : 'ZPE', 1 : 'HPE'}, 'plate_id' : {0 : '1', 1 : '1'}, 'response' : {0 : '14240', 1 : '147'}, 'cell_line_name' : {0 : 'H2009', 1 : 'H2009'}, 'cell_number_at_time0 ': {0 : '1000', 1 : '1000'}, 'response_stdev' : {0 : '1228', 1 : '23'} }) print(df)
输出结果:
drug1 plate_id response cell_line_name cell_number_at_time0 response_stdev 0 ZPE 1 14240 H2009 1000 1228 1 HPE 1 147 H2009 1000 23
我的需求是基于plate_id合并上述两行,生成对应药物的响应值和标准差列。DataFrame包含多个plate,我尝试过pandas的melt、wide_to_long、pivot方法但都没成功,尝试的代码如下:
stats_table_stdev=stats_table.pivot_table(columns='drug1', index=['plate_id', 'cell_line_name', 'cell_number_at_time0'], values='response_stdev') stats_table_stdev.rename(columns={'HPE':'HPE_std'}, inplace=True) stats_table_stdev.rename(columns={'ZPE':'ZPE_std'}, inplace=True) stats_table_export=pd.merge(left=stats_table_mean, right=stats_table_stdev, left_on=('plate_id', 'cell_line_name', 'cell_number_at_time0'), right_on=('plate_id', 'cell_line_name','cell_number_at_time0'))
解决方案
可以通过pivot或pivot_table直接完成分组展开,不需要额外的合并操作:
方法1:使用pivot(适用于无重复分组的场景)
# 按指定列分组,将drug1作为列展开,同时处理response和response_stdev pivoted = df.pivot( index=['plate_id', 'cell_line_name', 'cell_number_at_time0 '], columns='drug1', values=['response', 'response_stdev'] ) # 扁平化多级列名,拼接成「药物_字段名」的格式 pivoted.columns = [f'{drug}_{col}' for col, drug in pivoted.columns] # 将索引列转回普通列,得到最终结果 result = pivoted.reset_index()
运行后result的输出为:
plate_id cell_line_name cell_number_at_time0 ZPE_response HPE_response ZPE_response_stdev HPE_response_stdev 0 1 H2009 1000 14240 147 1228 23
方法2:使用pivot_table(适用于存在重复分组的场景)
如果你的DataFrame中存在同一plate_id+drug1组合的多行数据,需要聚合计算,可以指定聚合函数(如mean):
pivoted_table = df.pivot_table( index=['plate_id', 'cell_line_name', 'cell_number_at_time0 '], columns='drug1', values=['response', 'response_stdev'], aggfunc='mean' # 根据需求替换为sum、max等聚合函数 ) # 同样扁平化列名并重置索引 pivoted_table.columns = [f'{drug}_{col}' for col, drug in pivoted_table.columns] result_table = pivoted_table.reset_index()
注意事项
- 原DataFrame中
cell_number_at_time0列名末尾带有空格,处理时需保持一致,避免索引匹配错误 - 两种方法都直接完成了分组展开和列名格式化,无需额外执行
merge操作
内容的提问来源于stack exchange,提问作者chionj
相关产品推荐
相关产品推荐

