计算以列表形式存储的项目的价格
Calculate the price of Items in stored in list form
我有一个看起来像 this:Item-table
的 Dataframe
Date. Item.
10-sep. X,Y,Z
11-sep. Y,Z
12-sep. Z
13-sep. Z,X
还有另一个 Table,其中每件商品的价格按日期存储。价格-table
Item. 10sep. 11sep. 12sep. 13sep
X. 10. 5. 10. 15
Y. 7. 15. 13. 10
Z. 5. 10. 10. 10
我希望我的输出看起来像这样:
Date. Item. Total Price
10 sep. X,Y,Z. 22
11 sep. Y,Z. 25
12 sep. Z. 10
13 sep. Z,X. 25
第一行总点数为 22,因为 9 月 10 日 X、Y 和 Z 的价格分别为 10,7 和 5。我可以知道如何获得此输出列吗?
我将使用这个数据框来解决你的问题
print(df1)
Date Item
0 10-sep X,Y,Z
1 11-sep Y,Z
2 12-sep Z
3 13-sep Z,X
print(df2)
Item 10sep 11sep 12sep 13sep
0 X 10 5 10 15
1 Y 7 15 13 10
2 Z 5 10 10 10
我们可以使用DataFrame.lookup
到select数据框2的值,但首先我们必须准备值来做搜索:
df3=df1.copy()
df3['Item']=df3['Item'].str.split(',')
df3=df3.explode('Item')
df3['Date']=df3['Date'].str.replace('-','')
print(df3)
Date Item
0 10sep X
0 10sep Y
0 10sep Z
1 11sep Y
1 11sep Z
2 12sep Z
3 13sep Z
3 13sep X
mapper=df2.set_index('Item')
print(mapper)
10sep 11sep 12sep 13sep
Item
X 10 5 10 15
Y 7 15 13 10
Z 5 10 10 10
df3['value']=mapper.lookup(df3['Item'],df3['Date'])
df1['Total Price']=df3.groupby(level=0).value.sum()
print(df1)
Date Item Total Price
0 10-sep X,Y,Z 22
1 11-sep Y,Z 25
2 12-sep Z 10
3 13-sep Z,X 25
此数据帧的时间比较:
Valdi_Bo的方法:
%%timeit
ItemPrice = Prices.set_index('Item').stack().swaplevel().rename('Price')
def totalPrice(row):
dat = row.Date
items = row.Item.split(',')
ind = pd.MultiIndex.from_arrays([[dat] * len(items), items])
return ItemPrice.reindex(ind).sum()
Items['Total Price'] = Items.apply(totalPrice, axis=1)
13.5 ms ± 699 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
我的方法
%%timeit
df3=Items.copy()
df3['Item']=df3['Item'].str.split(',')
df3=df3.explode('Item')
mapper=Prices.set_index('Item')
df3['value']=mapper.lookup(df3['Item'],df3['Date'])
Items['Total Price']=df3.groupby(level=0).value.sum()
7.68 ms ± 178 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
@anky_91方法
%%timeit
m=df2.set_index('Item').T
n=df1[['Date']].assign(**df1['Item'].str.get_dummies(',')).set_index('Date')
final=df1.set_index('Date').assign(Total_Price=m.mul(n).sum(1)).reset_index()
8.7 ms ± 199 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
我假设你的两个 DataFrame 之间有一些最小的顺序和协调,即:
- 没有尾随点是列名。
- Prices 中列名的日期格式与 Items 中的 Date 列一样
(它们可以是 string 类型,但是 both 它们的天数后面都有一个负号。
所以商品和价格数据框实际上如下:
Date Item
0 10-sep X,Y,Z
1 11-sep Y,Z
2 12-sep Z
3 13-sep Z,X
Item 10-sep 11-sep 12-sep 13-sep
0 X 10 5 10 15
1 Y 7 15 13 10
2 Z 5 10 10 10
第一步是将价格转换为系列:
ItemPrice = Prices.set_index('Item').stack().swaplevel().rename('Price')
因此它包含:
Item
10-sep X 10
11-sep X 5
12-sep X 10
13-sep X 15
10-sep Y 7
11-sep Y 15
12-sep Y 13
13-sep Y 10
10-sep Z 5
11-sep Z 10
12-sep Z 10
13-sep Z 10
Name: Price, dtype: int64
然后定义一个函数来计算总价:
def totalPrice(row):
dat = row.Date
items = row.Item.split(',')
ind = pd.MultiIndex.from_arrays([[dat] * len(items), items])
return ItemPrice.reindex(ind).sum()
最后一步是将此函数应用于每一行并保存结果
作为新专栏:
Items['Total Price'] = Items.apply(totalPrice, axis=1)
结果是:
Date Item Total Price
0 10-sep X,Y,Z 22
1 11-sep Y,Z 25
2 12-sep Z 10
3 13-sep Z,X 25
利用@Valdi_Bo 提供的清理数据,您还可以尝试获取虚拟对象并与转置数据帧相乘并在 axis=1 上求和以获得所需的输出:
m=df2.set_index('Item').T
n=df1[['Date']].assign(**df1['Item'].str.get_dummies(',')).set_index('Date')
final=df1.set_index('Date').assign(Total_Price=m.mul(n).sum(1))
print(final)
Item Total_Price
Date
10-sep X,Y,Z 22
11-sep Y,Z 25
12-sep Z 10
13-sep Z,X 25
我有一个看起来像 this:Item-table
的 DataframeDate. Item.
10-sep. X,Y,Z
11-sep. Y,Z
12-sep. Z
13-sep. Z,X
还有另一个 Table,其中每件商品的价格按日期存储。价格-table
Item. 10sep. 11sep. 12sep. 13sep
X. 10. 5. 10. 15
Y. 7. 15. 13. 10
Z. 5. 10. 10. 10
我希望我的输出看起来像这样:
Date. Item. Total Price
10 sep. X,Y,Z. 22
11 sep. Y,Z. 25
12 sep. Z. 10
13 sep. Z,X. 25
第一行总点数为 22,因为 9 月 10 日 X、Y 和 Z 的价格分别为 10,7 和 5。我可以知道如何获得此输出列吗?
我将使用这个数据框来解决你的问题
print(df1)
Date Item
0 10-sep X,Y,Z
1 11-sep Y,Z
2 12-sep Z
3 13-sep Z,X
print(df2)
Item 10sep 11sep 12sep 13sep
0 X 10 5 10 15
1 Y 7 15 13 10
2 Z 5 10 10 10
我们可以使用DataFrame.lookup
到select数据框2的值,但首先我们必须准备值来做搜索:
df3=df1.copy()
df3['Item']=df3['Item'].str.split(',')
df3=df3.explode('Item')
df3['Date']=df3['Date'].str.replace('-','')
print(df3)
Date Item
0 10sep X
0 10sep Y
0 10sep Z
1 11sep Y
1 11sep Z
2 12sep Z
3 13sep Z
3 13sep X
mapper=df2.set_index('Item')
print(mapper)
10sep 11sep 12sep 13sep
Item
X 10 5 10 15
Y 7 15 13 10
Z 5 10 10 10
df3['value']=mapper.lookup(df3['Item'],df3['Date'])
df1['Total Price']=df3.groupby(level=0).value.sum()
print(df1)
Date Item Total Price
0 10-sep X,Y,Z 22
1 11-sep Y,Z 25
2 12-sep Z 10
3 13-sep Z,X 25
此数据帧的时间比较:
Valdi_Bo的方法:
%%timeit
ItemPrice = Prices.set_index('Item').stack().swaplevel().rename('Price')
def totalPrice(row):
dat = row.Date
items = row.Item.split(',')
ind = pd.MultiIndex.from_arrays([[dat] * len(items), items])
return ItemPrice.reindex(ind).sum()
Items['Total Price'] = Items.apply(totalPrice, axis=1)
13.5 ms ± 699 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
我的方法
%%timeit
df3=Items.copy()
df3['Item']=df3['Item'].str.split(',')
df3=df3.explode('Item')
mapper=Prices.set_index('Item')
df3['value']=mapper.lookup(df3['Item'],df3['Date'])
Items['Total Price']=df3.groupby(level=0).value.sum()
7.68 ms ± 178 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
@anky_91方法
%%timeit
m=df2.set_index('Item').T
n=df1[['Date']].assign(**df1['Item'].str.get_dummies(',')).set_index('Date')
final=df1.set_index('Date').assign(Total_Price=m.mul(n).sum(1)).reset_index()
8.7 ms ± 199 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
我假设你的两个 DataFrame 之间有一些最小的顺序和协调,即:
- 没有尾随点是列名。
- Prices 中列名的日期格式与 Items 中的 Date 列一样 (它们可以是 string 类型,但是 both 它们的天数后面都有一个负号。
所以商品和价格数据框实际上如下:
Date Item
0 10-sep X,Y,Z
1 11-sep Y,Z
2 12-sep Z
3 13-sep Z,X
Item 10-sep 11-sep 12-sep 13-sep
0 X 10 5 10 15
1 Y 7 15 13 10
2 Z 5 10 10 10
第一步是将价格转换为系列:
ItemPrice = Prices.set_index('Item').stack().swaplevel().rename('Price')
因此它包含:
Item
10-sep X 10
11-sep X 5
12-sep X 10
13-sep X 15
10-sep Y 7
11-sep Y 15
12-sep Y 13
13-sep Y 10
10-sep Z 5
11-sep Z 10
12-sep Z 10
13-sep Z 10
Name: Price, dtype: int64
然后定义一个函数来计算总价:
def totalPrice(row):
dat = row.Date
items = row.Item.split(',')
ind = pd.MultiIndex.from_arrays([[dat] * len(items), items])
return ItemPrice.reindex(ind).sum()
最后一步是将此函数应用于每一行并保存结果 作为新专栏:
Items['Total Price'] = Items.apply(totalPrice, axis=1)
结果是:
Date Item Total Price
0 10-sep X,Y,Z 22
1 11-sep Y,Z 25
2 12-sep Z 10
3 13-sep Z,X 25
利用@Valdi_Bo 提供的清理数据,您还可以尝试获取虚拟对象并与转置数据帧相乘并在 axis=1 上求和以获得所需的输出:
m=df2.set_index('Item').T
n=df1[['Date']].assign(**df1['Item'].str.get_dummies(',')).set_index('Date')
final=df1.set_index('Date').assign(Total_Price=m.mul(n).sum(1))
print(final)
Item Total_Price
Date
10-sep X,Y,Z 22
11-sep Y,Z 25
12-sep Z 10
13-sep Z,X 25