将数据框中每个ID的每一行数据转置为列。

3
我的数据框看起来是这样的。
id 年龄 性别 快照_1 表现_13 快照_5 表现_17 快照_7 表现_19
1 34 80 30 40 30
2 42 65 55 60 15 25 45
所有ID的数据需要按照以下方式进行分组,以便进行快照/性能统计。对于快照和相应的性能窗口,可以从第一个数据框中下划线后面的数字获取。
ID 年龄 性别 快照窗口 绩效窗口 快照值 绩效值
1 34 1 13
2 42 1 13 65 55
1 34 5 17 80 30
2 42 5 17 60 15
1 34 7 19 40 30
2 42 7 19 25 45

相关:如何对数据框进行透视?(总体概述) - wjandrea
3个回答

3

尝试:

x = pd.wide_to_long(
    df,
    stubnames="performance",
    sep="_",
    i=["id", "age", "Gender"],
    j="Performance_Window",
)[["performance"]].reset_index(level=3)

y = pd.wide_to_long(
    df,
    stubnames="snapshot",
    sep="_",
    i=["id", "age", "Gender"],
    j="Snapshot_Window",
)[["snapshot"]].reset_index(level=3)

print(
    pd.concat([x, y], axis=1)
    .reset_index()
    .rename(columns={"performance": "Performance_Value", "snapshot": "Snapshot_Value"})
)

输出:

   id  age Gender  Performance_Window Performance_Value  Snapshot_Window Snapshot_Value
0   1   34      M                  13                                  1               
1   1   34      M                  17                30                5             80
2   1   34      M                  19                30                7             40
3   2   42      F                  13                55                1             65
4   2   42      F                  17                15                5             60
5   2   42      F                  19                45                7             25

2
使用MultiIndex进行重塑,以处理任意数量的类别:

tmp = df.set_index(['id', 'age', 'Gender'])

idx = (tmp.columns.to_series().str.split('_', n=1, expand=True)
          .assign(n=lambda x: x.groupby(0).cumcount())
       )

out = (tmp
    .set_axis(pd.MultiIndex.from_frame(idx[[0, 'n']]), axis=1)
    .stack(dropna=False).add_suffix('_value')
    .reset_index(tmp.index.names)
    .join(idx.pivot(index='n', columns=0, values=1)
             .add_suffix('_window')
          )
    .rename_axis(index=None, columns=None)
 )

输出:

   id  age Gender  performance_value  snapshot_value performance_window snapshot_window
0   1   34      M                NaN             NaN                 13               1
0   2   42      F               55.0            65.0                 13               1
1   1   34      M               30.0            80.0                 17               5
1   2   42      F               15.0            60.0                 17               5
2   1   34      M               30.0            40.0                 19               7
2   2   42      F               45.0            25.0                 19               7

1
一种选择是使用pivot_longer - 在这种情况下,您传递多个values_to - 在这种情况下,names_pattern应该是一个匹配目标列的正则表达式列表,而names_to应该是与values_to长度相同的序列。
(df
.pivot_longer(
    index=['id','age','Gender'], 
    names_to=('snapshot_window', 'performance_window'), 
    values_to = ('snapshot_value', 'performance_value'), 
    names_pattern = ['snapshot','performance'])
.assign(snapshot_window=lambda df: df.snapshot_window
                                     .str.split("_").str[-1], 
        performance_window=lambda df: df.performance_window
                                       .str.split("_").str[-1])
)

   id  age Gender snapshot_window  snapshot_value performance_window  performance_value
0   1   34      M               1             NaN                 13                NaN
1   2   42      F               1            65.0                 13               55.0
2   1   34      M               5            80.0                 17               30.0
3   2   42      F               5            60.0                 17               15.0
4   1   34      M               7            40.0                 19               30.0
5   2   42      F               7            25.0                 19               45.0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接