如何将 Pandas groupby 中的行转换为列?

How to convert rows to columns in a Pandas groupby?

我有一个 table 包含一组产品超过 6 个月的价格数据。每件产品都有一个唯一的 ID (sku_id),尺码可以从 6 到 12 不等。我们每天测量价格,并生成类似于以下示例的 table。来源表示价格在哪个网站上(可以是 1-4)。

| sku_id | size | price | timestamp | source |

|    1   | 6.0  | 115.0 | 2021-01-10|   1    |
|    2   | 8.0  | 149.0 | 2021-01-10|   1    |
|    1   | 6.0  | 168.0 | 2021-01-10|   2    |
|    1   | 9.0  | 152.0 | 2021-01-10|   1    |
 ... 
|    1   | 9.0  | 152.0 | 2021-07-10|   1    |

现在,我想对上述数据集执行一些 analytics/modelling,但我无法根据需要对其进行格式化。我希望每个站点的每个产品都有一行(即键将是 [sku_id、大小、来源]),我们在新列中获取从 1 月 10 日到 7 月 1 日的每一天的价格。这在下面的 table 中表示。

| sku_id | size | source |price on 2021-01-10|price on 2021-01-11|price on 2021-01-12| ... |

|    1   | 6.0  |   1    |        149.0      |     151.2         |     158.2         | ... |
|    2   | 6.0  |   1    |        142.0      |     221.8         |     312.9         | ... |
 ...

我正在尝试在 Pandas 中使用分组依据(按 sku_id、大小和来源分组)来执行此操作,但我不确定如何指示 Pandas 为每一天添加一个新专栏。有人 instructions/advice 知道如何从第一个 table 构建第二个 table 吗?我不太确定如何让小组工作,我也不知道还有什么其他策略可以奏效。

我认为您的预期输出不正确。值 149 附加到 sku_id = 2 而这在预期输出中标记在 sku_id = 1 下。它将一些值从观察值转移到另一个值。

无论:

>>> df.set_index(['sku_id', 'size', 'source', 'timestamp']).unstack()
                        price           
timestamp          2021-01-10 2021-07-10
sku_id size source                      
1      6.0  1           115.0        NaN
            2           168.0        NaN
       9.0  1           152.0      152.0
2      8.0  1           149.0        NaN

然后减少您的柱状多索引:df.columns = [' '.join(col).strip() for col in df.columns.values] 以获得 price 2021-01-10 等。如果您想要不同的形式,请将其格式化以适合。

如果你想要重复的东西,reset_index

使用 pivot 转换您的数据框:

# pivot args: 1st -> index, 2nd -> columns, 3rd -> values
>>> df.pivot(['sku_id', 'size', 'source'], 'timestamp', 'price') \
      .rename_axis(columns=None).add_prefix('price on ').reset_index()

   sku_id  size  source  price on 2021-01-10  price on 2021-07-10
0       1   6.0       1                115.0                  NaN
1       1   6.0       2                168.0                  NaN
2       1   9.0       1                152.0                152.0
3       2   8.0       1                149.0                  NaN