使用分组数据(从长到宽)重塑 Pandas 数据帧

shi*_*shy 5 python reshape dataframe pandas

假设我有以下格式的数据:

group_id | entity_id | value
    A          a1        5
    A          a2        3
    A          a3        2
    B          b1        10
    B          b2        8
    B          b3        11
    C          c1        2
    C          c2        6
    C          c3        NaN
Run Code Online (Sandbox Code Playgroud)

表格1。

所以每个组(A/B/C)将有 3 个实体,保证。每个实体都有一个对应的值(如果不存在,有时是 NaN)。

我想将这些数据从现有格式重塑为...:

group_id | entity_1 | entity_2 | entity_3
   A          5          3          2
   B          10         8          11
   C          2          6          NaN
Run Code Online (Sandbox Code Playgroud)

表 2。

其中entity_1/entity_2/entity_3分别对应a1/a2/a3(或b1/b2/b3、c1/c2/c3)。

我该怎么做呢?

我发现的一种解决方案是使用枢轴函数,因此...

df.pivot(index='group_id', columns='entity_id', values='value')
Run Code Online (Sandbox Code Playgroud)

但据我所知,这个问题的问题在于,结果重整数据透视表中实体的列将不会采用我在上面表 2 中想要的格式——这对于我正在使用的一些下游内容很重要数据。

我可能会问一个愚蠢的问题,但我很难找到使用现有的枢轴/熔化函数以上述方式从长到宽的方法。谁能帮我吗?

如有必要,我很乐意提供更多详细信息,请告诉我!

jez*_*ael 5

您可以使用pivot并且新列是entity_id通过使用 str进行索引提取的列的最后一个值:

df = pd.pivot(index=df.group_id, columns=df.entity_id.str[-1], values=df.value)
       .add_prefix('entity_')
       .rename_axis(None, axis=1)
       .reset_index()
print (df)
  group_id  entity_1  entity_2  entity_3
0        A       5.0       3.0       2.0
1        B      10.0       8.0      11.0
2        C       2.0       6.0       NaN
Run Code Online (Sandbox Code Playgroud)

解决方案cumcount

df = pd.pivot(index=df.group_id,
              columns=df.groupby('group_id').cumcount() + 1, 
              values=df.value)
       .add_prefix('entity_')
       .reset_index()
print (df)
  group_id  entity_1  entity_2  entity_3
0        A       5.0       3.0       2.0
1        B      10.0       8.0      11.0
2        C       2.0       6.0       NaN
Run Code Online (Sandbox Code Playgroud)

使用groupbyand 的另一种解决方案apply,最后通过unstack以下方式重塑:

df = df.groupby("group_id")["value"]
       .apply(lambda x: pd.Series(x.values))
       .unstack()
       .add_prefix('entity_')
       .reset_index()
print (df)
  group_id  entity_0  entity_1  entity_2
0        A       5.0       3.0       2.0
1        B      10.0       8.0      11.0
2        C       2.0       6.0       NaN
Run Code Online (Sandbox Code Playgroud)

如果需要从1

df = df.groupby("group_id")["value"].apply(lambda x: pd.Series(x.values))
       .unstack()
       .rename(columns = lambda x: x+1)
       .add_prefix('entity_')
       .reset_index()
print (df)
  group_id  entity_1  entity_2  entity_3
0        A       5.0       3.0       2.0
1        B      10.0       8.0      11.0
2        C       2.0       6.0       NaN
Run Code Online (Sandbox Code Playgroud)