如何在 Python 中反转数据集

How to unpivot dataset in Python

我有一个数据集,我需要将其转换为多行到列。

例如:

ID  Currency    Val1    Val2        Month
101 INR     57007037.32 1292025.24  2021-03
101 INR     49171143.9  1303785.98  2021-02
101 INR     54039073.81 1469727.23  2021-01
101 INR     67733998.9  1370086.78  2020-12
101 INR     48838409.39 1203648.32  2020-11
101 INR     43119693.71 0           2020-10

我需要如下旋转/取消旋转它们。

ID  Currency    Keys        2021-03     2021-02         2021-01         2020-12     2020-11     2020-10
101 INR         Val1    57007037.32     49171143.9      54039073.81     67733998.9  48838409.39     4311.71
101 INR         Val2    1292025.24      1303785.98      1469727.23      1370086.78  1203648.32      0

我试过 df.melt 但那不是给出准确的输出。

df = pd.read_csv('/path/abc.csv')
print(df.melt(id_vars=['id'], var_name=['month'], value_vars=['val1','val2']))

请帮忙解决这个问题。

1。 stackunstack

(df.set_index(['ID', 'Currency', 'Month']).stack()
  .unstack(-2).reset_index().rename(columns={'level_2': 'keys'}))

2。 Meltpivot

df.melt(['ID', "Currency", 'Month'], var_name='keys')\
  .pivot(['ID', 'Currency', 'keys'], 'Month', 'value').reset_index()

Month   ID Currency  keys      2020-10      2020-11      2020-12      2021-01      2021-02      2021-03
0      101      INR  Val1  43119693.71  48838409.39  67733998.90  54039073.81  49171143.90  57007037.32
1      101      INR  Val2         0.00   1203648.32   1370086.78   1469727.23   1303785.98   1292025.24

另一个版本使用 .pivot:

print(
    pd.pivot(
        df,
        index=["ID", "Currency"],
        columns="Month",
        values=["Val1", "Val2"],
    )
    .stack(level=0)
    .reset_index()
    .rename(columns={"level_2": "keys"})
)

打印:

Month   ID Currency  keys      2020-10      2020-11      2020-12      2021-01      2021-02      2021-03
0      101      INR  Val1  43119693.71  48838409.39  67733998.90  54039073.81  49171143.90  57007037.32
1      101      INR  Val2         0.00   1203648.32   1370086.78   1469727.23   1303785.98   1292025.24

编辑:适用于 pandas=0.22.0 的解决方案:

print(
    df.set_index(["ID", "Currency"])
    .pivot(columns="Month")
    .stack(level=0)
    .reset_index()
    .rename(columns={"level_2": "keys"})
)

打印:

Month   ID Currency  keys      2020-10      2020-11      2020-12      2021-01      2021-02      2021-03
0      101      INR  Val1  43119693.71  48838409.39  67733998.90  54039073.81  49171143.90  57007037.32
1      101      INR  Val2         0.00   1203648.32   1370086.78   1469727.23   1303785.98   1292025.24

编辑:对列进行排序:

x = (
    df.set_index(["ID", "Currency"])
    .pivot(columns="Month")
    .stack(level=0)
    .reset_index()
    .rename(columns={"level_2": "keys"})
)
x.columns.name = ""
x = x[["ID", "Currency", "keys"] + sorted(x.columns, reverse=True)[3:]]
print(x)

打印:

    ID Currency  keys      2021-03      2021-02      2021-01      2020-12      2020-11      2020-10
0  101      INR  Val1  57007037.32  49171143.90  54039073.81  67733998.90  48838409.39  43119693.71
1  101      INR  Val2   1292025.24   1303785.98   1469727.23   1370086.78   1203648.32         0.00

另一种方法:

>>> df.groupby(["ID", "Currency"]) \
      .apply(lambda x: x[["Month", "Val1", "Val2"]] \
                       .set_index("Month") \
                       .rename_axis(columns="Key") \
                       .transpose())

Month                  2021-03      2021-02      2021-01      2020-12      2020-11      2020-10
ID  Currency Key
101 INR      Val1  57007037.32  49171143.90  54039073.81  67733998.90  48838409.39  43119693.71
             Val2   1292025.24   1303785.98   1469727.23   1370086.78   1203648.32         0.00

对于0.24之前的Pandas版本,将rename_axis(columns="Key")更改为rename_axis("Key", axis="columns")

使用 set_index + unstack + stack:

(df.set_index(['ID', 'Month', 'Currency']).unstack('Month')
.stack(level=0).rename_axis(index={None: 'Keys'}).reset_index())

Month ID    Currency  Keys  2020-10     2020-11     2020-12     2021-01     2021-02     2021-03
0     101   INR       Val1  43119693.71 48838409.39 67733998.90 54039073.81 49171143.90 57007037.32
1     101   INR       Val2  0.00        1203648.32  1370086.78  1469727.23  1303785.98  1292025.24