假设我有以下格式的数据:
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
表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
表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')
但据我所知,这个问题是生成的重新整形数据透视表中实体的列将不会采用我在上面表2中所希望的格式 - 这对于某些下游内容我很重要处理数据。
我可能会问一个愚蠢的问题,但我很难找到使用现有的枢轴/融合功能的方法,从上面描述的方式从长到宽。任何人都可以帮助我吗?
如果有必要,我很乐意提供更多详细信息,请告诉我!
答案 0 :(得分:3)
您可以使用pivot
,新列是indexing with str提取的列entity_id
的最后一个值:
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
和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
如果需要从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