假设我有一个像这样的数据框:
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)
我想创建一个名为“平均商品价格”的新属性,该属性是通过将每个商店/日期/付款方式的销售额除以商品而生成的(例如,对于商店 5123,2021-01- 01,现金,我想创建一个新行,其属性名为“平均商品价格”,其值等于 5.25)。
我意识到我可以将这些数据转出,一列用于销售,一列用于商品,然后划分两列,然后重新堆叠,但是有没有更好的方法可以在不进行数据透视的情况下做到这一点?
最佳答案
您可以使用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/