【问题标题】:How can I reshape a wide dataset into a long dataset using multiple columns?如何使用多列将宽数据集重塑为长数据集?
【发布时间】:2020-12-12 03:44:00
【问题描述】:

我有一个需要重塑的数据框

ID Treatment Dog_Weight Cat_Weight Horse_Weight Pig_Weight
1     A         20         10          100         1000 
2     A         30         20          200         550
3     A         40         30          300         750
4     A         50         40          400         800
5     B         60         50          500         650
6     B         70         60          600         450
7     B         80         70          700         500
8     B         90         80          800         600

我正在尝试让它看起来像这样:

    ID  Animal  Animal_Weight_A Animal_Weight_B
0   1    Dog         20            60
1   2    Dog         30            70
2   3    Dog         40            80
3   4    Dog         50            90
4   1    Cat         10            50
5   2    Cat         20            60
6   3    Cat         30            70
7   4    Cat         40            80
8   1    Horse      100            500
9   2    Horse      200            600
10  3    Horse      300            700
11  4    Horse      400            800
12  1    Pig        1000           650
13  2    Pig        550            450
14  3    Pig        750            500
15  4    Pig        800            600

我已经能够使用以下步骤做到这一点:

  1. Groupby 以获取每只动物的汇总信息:
df_test1 = (
    df.groupby(["ID", "Treatment"])[
        "Dog_Weight", "Cat_Weight", "Horse_Weight", "Pig_Weight"
    ]
    .mean()
    .reset_index()
)
  1. 融合数据以将动物放入列中:
df_test2 = pd.melt(
    df_test1,
    id_vars=["ID", "Treatment"],
    value_vars=["Dog_Weight", "Cat_Weight", "Horse_Weight", "Pig_Weight"],
).rename(columns={"variable": "Animal", "value": "Animal_Weight"})
  1. 提取动物名称
df_test2["Animal"] = df_test2["Animal"].str.split("_").str[0]
  1. 按处理分开
test_A = df_test2.query("Treatment == 'A'")
test_B = df_test2.query("Treatment == 'B'")
  1. 合并 ID 和 Animal 以重新组合数据集,删除不必要的列
df_testfinal = pd.merge(
    test_A,
    test_B,
    on=["ID", "Animal"],
    suffixes=("_A", "_B"),
).drop(["Treatment_A", "Treatment_B"], axis=1)

虽然这种方法有效,但似乎有一种方法可以使用 reshape/pivot/melt 来完成。我希望有人可以帮助我找到一种方法来使用其中一种方法或减少步骤数?

谢谢!

【问题讨论】:

    标签: python pandas reshape


    【解决方案1】:

    让我们先尝试融化,然后旋转:

    tmp = df.melt(['ID','Treatment'], var_name='Animal')
    tmp['Animal'] = tmp['Animal'].str.extract('^([^_]+)')
    tmp['ID'] = tmp.groupby(['Animal','Treatment']).cumcount()
    
    out = (tmp.pivot_table(index=['Animal','ID'], columns=['Treatment'], 
                          values='value')
           .add_prefix('Animal_Weight_').reset_index()
          )
    

    输出:

    Treatment Animal  ID  Animal_Weight_A  Animal_Weight_B
    0            Cat   0               10               50
    1            Cat   1               20               60
    2            Cat   2               30               70
    3            Cat   3               40               80
    4            Dog   0               20               60
    5            Dog   1               30               70
    6            Dog   2               40               80
    7            Dog   3               50               90
    8          Horse   0              100              500
    9          Horse   1              200              600
    10         Horse   2              300              700
    11         Horse   3              400              800
    12           Pig   0             1000              650
    13           Pig   1              550              450
    14           Pig   2              750              500
    15           Pig   3              800              600
    

    【讨论】:

      猜你喜欢
      • 2018-06-15
      • 1970-01-01
      • 1970-01-01
      • 2018-05-14
      • 1970-01-01
      • 2021-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多