首页 > 解决方案 > 使用 Pandas 将(部分)垂直 DataFrame 转换为水平

问题描述

我有一个脚本可以创建一个看起来像这样的 df(还有许多其他属性列)

因此,对于每个ITEM_IDX,我都有一个时间标识符(QM_ID)和一个值(VALUE

ITEM_IDX;XVAL;YVAL;ZVAL;PT_ID;...;QM_ID;VALUE
1;635000;5020000;15.1;1000000;...;6000;0.00
2;635010;5020000;15.0;1000001;...;6000;0.56
3;635020;5020000;15.2;1000002;...;6000;0.45
1;635000;5020000;15.1;1000000;...;6001;0.10
2;635010;5020000;15.0;1000001;...;6001;0.55
3;635020;5020000;15.2;1000002;...;6001;0.48
1;635000;5020000;15.1;1000000;...;6002;0.13
2;635010;5020000;15.0;1000001;...;6002;0.50
3;635020;5020000;15.2;1000002;...;6002;0.41

我需要创建一个像这样格式化的输出。
对于每个ITEM_IDX,我想要每个 QM_ID 的列VALUE作为其值。

ITEM_IDX;XVAL;YVAL;ZVAL;PT_ID;...;QM_ID_6000;QM_ID_6001;QM_ID_6002
1;635000;5020000;15.1;1000000;...;0.00;0.10;0.13
2;635010;5020000;15.0;1000001;...;0.56;0.55;0.50
3;635020;5020000;15.2;1000002;...;0.45;0.48;0.41

这是一个最多 1M 行的 df,最多有 4k 个不同的QM_ID,因此输出将有很多列。(是的,我知道...)

我尝试使用主要列创建一个新的 df,然后按 QM_ID 对我的 df 进行分组并一一添加列,但这很慢而且不是真正的“pythonic”。我正在寻找一种更快、更有效的方法,因为我必须经常这样做。

非常感谢 :)

PS:我正在使用 python 3.7.9 和 pandas 1.1.3

编辑,我目前的“解决方案”:

my_df = pd.read_csv(datafile, sep=';')
my_df_result = my_df[['ITEM_IDX','XVAL','YVAL','ZVAL','PT_ID']].drop_duplicates(subset=['ITEM_IDX'], keep='first')
for q in my_df['QM_ID'].unique().tolist():
    my_df_result[f'QM_ID_{q}'] = my_df[my_df['QM_ID'] == q]['VALUE'].tolist()

标签: pythonpython-3.xpandasdataframe

解决方案


尝试这个:

df.pivot(['ITEM_IDX', 'XVAL', 'YVAL', 'ZVAL', 'PT_ID'], 'QM_ID', 'VALUE')\
  .add_prefix('QM_ID_').reset_index()

输出:

QM_ID  ITEM_IDX    XVAL     YVAL  ZVAL    PT_ID  QM_ID_6000  QM_ID_6001  QM_ID_6002
0             1  635000  5020000  15.1  1000000        0.00        0.10        0.13
1             2  635010  5020000  15.0  1000001        0.56        0.55        0.50
2             3  635020  5020000  15.2  1000002        0.45        0.48        0.41

pivot 您的数据框定义行和列,然后用于add_prefix正确命名列,然后reset_index


推荐阅读