按ID重塑DataFrame:高效实现多行转多列的批量数据变形
问题描述
我有一个包含1个ID列和24个值列的DataFrame,每个ID对应49行数据。需要将每个ID对应的49×24数据重塑为7×168结构,保持顺序,下一行数据追加到上一行右侧。示例如下:
输入DataFrame示例
ID Column_1 Column_2 ... Column_22 Column_23 Column_24 0 1 39 86 ... 74 89 91 1 1 37 25 ... 71 66 6 ... 48 1 38 23 ... 74 80 79
期望输出DataFrame示例
ID Column_1 Column_2 ... Column_166 Column_167 Column_168 0 1 64 33 ... 67 40 32 ... 6 1 49 58 ... 13 46 20
同时需要对数据框中数千个ID执行相同操作。曾尝试循环实现,但该规模数据运行极慢,求更简便高效的重塑方法。
补充:简化示例生成代码
输入示例生成代码
import pandas as pd ids = [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4] columns_data = [] for i in range(1, 8): column_data = [i + 7 * j for j in range(len(ids))] columns_data.append(column_data) data = {'ID': ids} for i in range(7): column_name = f'Column_{i + 1}' data[column_name] = columns_data[i] df = pd.DataFrame(data) print(df)
对应期望输出生成代码
import pandas as pd ids = [1, 1, 2, 2, 3, 3, 4, 4,] columns_data = [] for i in range(1, 15): column_data = [i + 14 * j for j in range(len(ids))] columns_data.append(column_data) data = {'ID': ids} for i in range(14): column_name = f'Column_{i + 1}' data[column_name] = columns_data[i] df = pd.DataFrame(data) print(df)
高效重塑方案
利用pandas分组与numpy向量化重塑操作替代循环,大幅提升处理效率,具体实现如下:
核心逻辑
每个ID对应49行数据,按7行一组拆分,每组内将7行的24列数据横向拼接为1行(共7*24=168列),最终每个ID对应7行168列的结果。通过分组后对组内数据进行形状重塑,避免Python层面循环。
代码实现
import pandas as pd def reshape_group(group): # 提取当前组的数值部分,去除ID列 values = group.drop('ID', axis=1).values # 重塑形状:49行24列 → 7行168列(按顺序将每7行的24列横向拼接) reshaped_values = values.reshape(7, 7*24) # 构造新列名 new_columns = [f'Column_{i+1}' for i in range(7*24)] # 创建新的组DataFrame new_group = pd.DataFrame(reshaped_values, columns=new_columns) # 添加ID列(当前组的ID值) new_group['ID'] = group['ID'].iloc[0] # 将ID列移至首位 new_group = new_group[['ID'] + new_columns] return new_group # 分组处理并合并结果 result_df = df.groupby('ID', group_keys=False).apply(reshape_group).reset_index(drop=True)
简化示例验证
针对你提供的简化输入(每个ID4行7列,需转为2行14列),只需调整重塑参数即可:
def reshape_group_simplified(group): values = group.drop('ID', axis=1).values reshaped_values = values.reshape(2, 2*7) new_columns = [f'Column_{i+1}' for i in range(2*7)] new_group = pd.DataFrame(reshaped_values, columns=new_columns) new_group['ID'] = group['ID'].iloc[0] new_group = new_group[['ID'] + new_columns] return new_group # 生成简化输入后执行 result_simplified = df.groupby('ID', group_keys=False).apply(reshape_group_simplified).reset_index(drop=True) print(result_simplified)
运行结果与你提供的期望输出完全一致,验证方法有效性。
效率说明
此方案依赖numpy底层C实现的向量化操作,避免了纯Python循环的性能损耗,处理数千个ID时速度会比循环实现提升数倍甚至数十倍。
内容的提问来源于stack exchange,提问作者Hupatin
相关产品推荐
相关产品推荐

