python - Pandas - 通过划分EAV格式数据为组创建新的属性和值

标签 python pandas

假设我有一个像这样的数据框:

import pandas as pd
import numpy as np

data = [[5123, '2021-01-01 00:00:00', 'cash','sales$', 105],
        [5123, '2021-01-01 00:00:00', 'cash','items', 20],
        [5123, '2021-01-01 00:00:00', 'card','sales$', 355],
        [5123, '2021-01-01 00:00:00', 'card','items', 50],
        [5123, '2021-01-02 00:00:00', 'cash','sales$', np.nan],
        [5123, '2021-01-02 00:00:00', 'cash','items', np.nan],
        [5123, '2021-01-02 00:00:00', 'card','sales$', 170],
        [5123, '2021-01-02 00:00:00', 'card','items', 35]]

columns = ['Store', 'Date', 'Payment Method', 'Attribute', 'Value']

df = pd.DataFrame(data = data, columns = columns)

<表类=“s-表”> <标题> 商店 日期 付款方式 属性 值 <正文> 5123 2021-01-01 00:00:00 现金 销售额$ 105 5123 2021-01-01 00:00:00 现金 项目 20 5123 2021-01-01 00:00:00 卡 销售额$ 355 5123 2021-01-01 00:00:00 卡 项目 50 5123 2021-01-02 00:00:00 现金 销售额$ NaN 5123 2021-01-02 00:00:00 现金 项目 NaN 5123 2021-01-02 00:00:00 卡 销售额$ 170 5123 2021-01-02 00:00:00 卡 项目 35

我想创建一个名为“平均商品价格”的新属性,该属性是通过将每个商店/日期/付款方式的销售额除以商品而生成的(例如,对于商店 5123,2021-01- 01,现金,我想创建一个新行,其属性名为“平均商品价格”,其值等于 5.25)。

我意识到我可以将这些数据转出,一列用于销售,一列用于商品,然后划分两列,然后重新堆叠,但是有没有更好的方法可以在不进行数据透视的情况下做到这一点?

<表类=“s-表”> <标题> 商店 日期 付款方式 属性 值 <正文> 5123 2021-01-01 00:00:00 现金 销售额$ 105 5123 2021-01-01 00:00:00 现金 项目 20 5123 2021-01-01 00:00:00 现金 平均商品价格 5.25 5123 2021-01-01 00:00:00 卡 销售额$ 355 5123 2021-01-01 00:00:00 卡 项目 50 5123 2021-01-01 00:00:00 卡 平均商品价格 7.10 5123 2021-01-02 00:00:00 现金 销售额$ NaN 5123 2021-01-02 00:00:00 现金 项目 NaN 5123 2021-01-02 00:00:00 现金 平均商品价格 NaN 5123 2021-01-02 00:00:00 卡 销售额$ 170 5123 2021-01-02 00:00:00 卡 项目 35 5123 2021-01-02 00:00:00 卡 平均商品价格 4.86

最佳答案

您可以使用pivot_table获取每组的销售额/商品总和,然后计算平均值并与原始数据合并:

s = (df.pivot_table(index=['Store', 'Date', 'Payment Method'],
                    columns='Attribute', values='Value', aggfunc='sum')
       .assign(avg=lambda d: d['sales$']/d['items'])
       ['avg']
     )

df.merge(s, left_on=['Store', 'Date', 'Payment Method'], right_index=True)

输出:

   Store                 Date Payment Method Attribute  Value       avg
0   5123  2021-01-01 00:00:00           cash    sales$  105.0  5.250000
1   5123  2021-01-01 00:00:00           cash     items   20.0  5.250000
2   5123  2021-01-01 00:00:00           card    sales$  355.0  7.100000
3   5123  2021-01-01 00:00:00           card     items   50.0  7.100000
4   5123  2021-01-02 00:00:00           cash    sales$    NaN       NaN
5   5123  2021-01-02 00:00:00           cash     items    NaN       NaN
6   5123  2021-01-02 00:00:00           card    sales$  170.0  4.857143
7   5123  2021-01-02 00:00:00           card     items   35.0  4.857143

连接

df2 = (df.pivot_table(index=['Store', 'Date', 'Payment Method'],
                      columns='Attribute', values='Value', aggfunc='sum')
         .assign(Attribute='average item price',
                 Value=lambda d: d['sales$']/d['items'],
                 )
         .reset_index()
       )

(pd.concat([df,df2])
   .sort_values(by=columns)
   [columns]
 )

输出:

   Store                 Date Payment Method           Attribute       Value
0   5123  2021-01-01 00:00:00           card  average item price    7.100000
3   5123  2021-01-01 00:00:00           card               items   50.000000
2   5123  2021-01-01 00:00:00           card              sales$  355.000000
1   5123  2021-01-01 00:00:00           cash  average item price    5.250000
1   5123  2021-01-01 00:00:00           cash               items   20.000000
0   5123  2021-01-01 00:00:00           cash              sales$  

关于python - Pandas - 通过划分EAV格式数据为组创建新的属性和值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70203165/

相关文章:

python - 如何修复 "latin-1 codec can' t 在请求中的位置编码字符

python - 从多个数据帧获取 int 单元格的总和

python: ValueError: 从 excel 中解压(预期 2)数据的值太多

Python - Django Manage.py Syncdb 失败?

Python:定时器,如何在程序结束时停止线程?

python - If-None-Match header 未接受请求 header

python - SmartyStreets API 在数据框架中循环

python - 如何按年份计算 pandas dataframe 列中最常出现的单词?

python - 将 JSON 读入 Python/Pandas - 获取 JSONDecodeError

python - Dask 诊断 - 带 map_partition/delayed 的进度条