如何在Pandas中按条件将多行合并为单行?
Pandas按条件合并多行到单行的解决思路
这问题我之前也碰到过类似的,核心思路是先给数据分组,再对每个组内的内容做针对性整理聚合。我结合你的示例拆解成具体步骤,直接上可运行的代码和解释:
1. 先构造示例数据(方便测试)
首先把你给出的示例转成可操作的DataFrame:
import pandas as pd import numpy as np data = [ ['data1', np.nan, np.nan, np.nan], ['string1', 'num1', 'ex1', 'bla1'], ['string2', np.nan, np.nan, np.nan], ['string3', np.nan, np.nan, np.nan], ['data2', np.nan, np.nan, np.nan], ['string4', 'num2', 'ex2', 'bla2'], ['string5', np.nan, np.nan, np.nan] ] df = pd.DataFrame(data, columns=['col0', 'col1', 'col2', 'col3'])
2. 生成分组ID(核心步骤)
我们需要把data1、data2作为每个组的“锚点”,给后续的行分配同一个组ID,直到遇到下一个data开头的行:
# 当col0以'data'开头时,组号递增,其他行继承当前组号 df['group_id'] = df['col0'].str.startswith('data').cumsum()
这一步运行后,data1和它下面的3行group_id都是1,data2和它下面的2行group_id都是2,这样就把数据分成了两个独立的组。
3. 定义组内处理函数
对每个组,我们需要完成三件事:提取data标签、收集所有string行、提取num/ex/bla相关值,然后合并成一行:
def process_single_group(group): # 提取组内的data标签(每个组只有一个) data_tag = group[group['col0'].str.startswith('data')]['col0'].iloc[0] # 收集组内所有string开头的行内容 string_list = group[group['col0'].str.startswith('string')]['col0'].tolist() # 提取组内带num/ex/bla的行的非空值(排除col0和group_id列) meta_info = group.drop(['col0', 'group_id'], axis=1).dropna(how='all').values.flatten().tolist() # 把所有内容合并成一个列表 return [data_tag] + string_list + meta_info
4. 分组聚合生成结果
把上面的函数应用到每个组,再转成最终的DataFrame并设置列名:
# 按group_id分组处理,将结果转成Series再拼接成DataFrame result_df = df.groupby('group_id').apply(process_single_group).apply(pd.Series) # 给结果设置合适的列名(根据你的需求调整) result_df.columns = [ 'data', 'string1', 'string2', 'string3', # 对应收集到的string行 'num', 'ex', 'bla' # 对应num/ex/bla的值 ]
运行完上面的代码,你就能得到和示例完全一致的结果啦!
补充说明
- 如果你的数据中
string行数量不固定(比如有的组2个,有的组5个),代码也能自动适配,列名可以用循环生成,比如:str_cols = [f'string{i+1}' for i in range(result_df.shape[1]-4)] other_cols = ['num', 'ex', 'bla'] result_df.columns = ['data'] + str_cols + other_cols - 如果组内可能有多行带
num/ex/bla的情况,可以根据需求调整meta_info的提取逻辑,比如取第一行、合并所有行等。
内容的提问来源于stack exchange,提问作者Abdulla Salimov
相关产品推荐
相关产品推荐

