如何按行和列重构Pandas DataFrame?
问题描述
我有一个如下结构的Pandas DataFrame:
import pandas as pd tuples = [ ['00:00:00','','','00:00:15','','','00:00:30','',''], ['37.0','','','37.1','','','36.9','',''] ] index = pd.MultiIndex.from_arrays(tuples, names=['time', 'temp']) df = pd.DataFrame( data=[ ['A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'A10', 'A11', 'A12'], ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B9', 'B10', 'B11', 'B12'], ['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9', 'C10', 'C11', 'C12'], ['A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'A10', 'A11', 'A12'], ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B9', 'B10', 'B11', 'B12'], ['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9', 'C10', 'C11', 'C12'], ['A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'A10', 'A11', 'A12'], ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B9', 'B10', 'B11', 'B12'], ['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9', 'C10', 'C11', 'C12'] ], index=index, columns=(range(12)) )
DataFrame显示效果如下:
0 1 2 3 4 5 6 7 8 9 10 11 time temp 00:00:00 37.0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 00:00:15 37.1 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 00:00:30 36.9 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12
其中A1、A2等实际为数值,为简化用坐标展示。我希望将其重构为如下形式:
time temp 00:00:00 37.0 A1 A2 ... C10 C11 C12 00:00:15 37.1 A1 A2 ... C10 C11 C12 00:00:30 36.9 A1 A2 ... C10 C11 C12
尝试过循环行处理和添加辅助列后使用groupby,但均未完全解决问题,也不清楚该查阅Pandas文档的哪部分内容。
解决方案
核心思路
你要做的就是把同一个time和temp对应的3行数据合并成一行,本质是分组后把多行内容平铺成一行。先把索引里的空值补上,再用分组拼接就能解决。
具体代码
# 先把索引里的空值填充成前一行的有效值,让同一组的行共享相同的time和temp标签 df.index = df.index.fillna(method='ffill') # 按time和temp分组,把每组的所有数据平铺成一行 result = df.groupby(level=['time', 'temp']).apply(lambda x: pd.Series(x.values.flatten())) # 可选:给新列设置名称,比如按顺序命名 result.columns = [f'val_{i+1}' for i in range(result.shape[1])]
步骤说明
- 补全索引空值:原索引里的空值会导致分组失败,用
fillna(method='ffill')把空值替换成前面的有效值,这样同一时间、温度下的3行就会被归为一组。 - 分组平铺数据:通过
groupby按time和temp分组,然后用apply把每组的所有值压成一维数组,转成Series后每组就变成了一行。 - 列命名(可选):如果需要给新列起名字,直接给
columns赋值就行。
该查的文档部分
你可以重点看Pandas文档里这几块:
- 多索引(MultiIndex)的填充与分组
groupby结合apply的自定义聚合操作- 数据重塑里的行扁平化、拼接相关内容
内容的提问来源于stack exchange,提问作者p1xel
相关产品推荐
相关产品推荐

