如何在Pandas列转行时限制行数,替代explode的笛卡尔积?
实现Pandas中按列最长列表长度对齐的列转行
问题描述
原始数据中,每组title和name对应的Type、Method、Object列均为多值列表:比如某组里Type有3个值、Method有2个值、Object有4个值。
用Pandas自带的DataFrame.explode()方法处理时,会生成各列值数量乘积的行数(此案例是3×2×4=24行),但实际需要的是每组行数等于三列中最长列表的长度(此案例为4行),长度不足的列用空值填充对齐。
解决方案
可以通过先对齐列表长度,再执行explode的方式实现,具体代码如下:
import pandas as pd import numpy as np # 模拟你的原始数据结构 df = pd.DataFrame({ 'title': ['Title1', 'Title2'], 'name': ['Name1', 'Name2'], 'Type': [['T1', 'T2', 'T3'], ['T4', 'T5']], 'Method': [['M1', 'M2'], ['M3']], 'Object': [['O1', 'O2', 'O3', 'O4'], ['O5', 'O6', 'O7']] }) def align_then_explode(group): # 获取当前分组内所有列表列的最大长度 max_length = max( len(group['Type'].iloc[0]), len(group['Method'].iloc[0]), len(group['Object'].iloc[0]) ) # 把每个列表补到最大长度,不足的位置用NaN填充 group['Type'] = [group['Type'].iloc[0] + [np.nan] * (max_length - len(group['Type'].iloc[0]))] group['Method'] = [group['Method'].iloc[0] + [np.nan] * (max_length - len(group['Method'].iloc[0]))] group['Object'] = [group['Object'].iloc[0] + [np.nan] * (max_length - len(group['Object'].iloc[0]))] # 对补全后的列执行explode return group.explode(['Type', 'Method', 'Object']) # 分组处理并合并结果 final_df = df.groupby(['title', 'name'], group_keys=False).apply(align_then_explode).reset_index(drop=True) print(final_df)
关键说明
- 按
title和name分组后,先计算当前组内最长列表的长度; - 将所有列的列表补全到该长度,空白位置用
np.nan填充(如果需要重复最后一个值,把np.nan换成group['Type'].iloc[0][-1]这类写法即可); - 最后执行
explode,就能得到按最长列表对齐的结果,行数等于最长列表的长度。
内容的提问来源于stack exchange,提问作者Kevin Song
相关产品推荐
相关产品推荐

