使用分组数据重塑 Pandas 数据框(从长到宽)
Reshaping Pandas Dataframe with Grouped Data (Long to Wide)
假设我有以下格式的数据:
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
Table 1.
所以每个组 (A/B/C) 将有 3 个实体,保证。
每个实体都有一个对应的值(如果不存在,有时为 NaN)。
我想将现有格式的数据重塑为...:[=14=]
group_id | entity_1 | entity_2 | entity_3
A 5 3 2
B 10 8 11
C 2 6 NaN
Table 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')
但据我了解,问题在于生成的重塑枢轴 table 中实体的列将不是我在上面 Table 中想要的格式 2 --这对于我处理数据的一些下游工作很重要。
我可能会问一个愚蠢的问题,但我无法找到使用现有 pivot/melt 函数按照我上面描述的方式从长到宽的方法。谁能帮帮我?
如有必要,我很乐意提供更多详细信息,请告诉我!
您可以使用 pivot
and new columns are last value of column entity_id
extracted by indexing with 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
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
另一个解决方案groupby
and apply
, last reshape by 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
如果需要从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
假设我有以下格式的数据:
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
Table 1.
所以每个组 (A/B/C) 将有 3 个实体,保证。 每个实体都有一个对应的值(如果不存在,有时为 NaN)。
我想将现有格式的数据重塑为...:[=14=]
group_id | entity_1 | entity_2 | entity_3
A 5 3 2
B 10 8 11
C 2 6 NaN
Table 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')
但据我了解,问题在于生成的重塑枢轴 table 中实体的列将不是我在上面 Table 中想要的格式 2 --这对于我处理数据的一些下游工作很重要。
我可能会问一个愚蠢的问题,但我无法找到使用现有 pivot/melt 函数按照我上面描述的方式从长到宽的方法。谁能帮帮我?
如有必要,我很乐意提供更多详细信息,请告诉我!
您可以使用 pivot
and new columns are last value of column entity_id
extracted by indexing with 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
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
另一个解决方案groupby
and apply
, last reshape by 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
如果需要从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