首页 > 解决方案 > 融化/取消透视具有多组值的数据集

问题描述

我正在尝试在 Python 中转换数据框,但我被卡住了,因为我不知道如何准确表达我想要做的事情(这使得搜索变得困难)。看来我需要 unstack 和 pivot 的组合。不过,我可以用一个例子来解释它,希望如此。我有一个这种形状的数据框:

用户身份 GroupA_measure1 GroupA_measure2 GroupB_measure1 GroupB_measure2
001 65 70 45 50
002 96 89 12 8
003 12 14 38 40

我想把它转换成这种格式:

用户身份 措施 A组 B组
001 1 65 45
001 2 70 50
002 1 96 12
002 2 89 8
003 1 12 38
003 2 14 40

我可以使用将所有值放在单独的行中来取消堆叠整个 df pd.melt(df, id_vars =['userid']),但我想为 GroupA 和 GroupB 的值保留单独的列。

任何帮助将非常感激。

标签: pythonpandaspivot-tablepandas-melt

解决方案


与从列wide_to_long中提取数字一起使用:measureSeries.str.extract

df1 = pd.wide_to_long(df, 
                      stubnames=['GroupA','GroupB'], 
                      i='userid', 
                      j='measure', sep='_', suffix=r'\w+').reset_index()

df1['measure'] = df1['measure'].str.extract('(\d+)').astype(int)

或者_先转换非列,用 拆分所有列_并重塑形状DataFrame.stack,最后还提取数字:

df1 = df.set_index('userid')
df1.columns = df1.columns.str.split('_', expand=True)
df1 = df1.rename_axis((None, 'measure'), axis=1).stack().reset_index()
df1['measure'] = df1['measure'].str.extract('(\d+)').astype(int)
print (df1)
  userid  measure GroupA GroupB
0    001        1     65     45
1    002        1     96     12
2    003        1     12     38
3    001        2     70     50
4    002        2     89      8
5    003        2     14     40

如有必要,最后按以下方式排序DataFrame.sort_values

df1 = df1.sort_values('userid', ignore_index=True)
print (df1)
  userid  measure GroupA GroupB
0    001        1     65     45
1    001        2     70     50
2    002        1     96     12
3    002        2     89      8
4    003        1     12     38
5    003        2     14     40

推荐阅读