我具有公司出售给许多不同客户的商品的数量和金额(在交易中收取了多少)的历史数据。我希望对此数据进行一些时间序列分析,但希望在项目客户级别进行。
这是我的原始数据:
Year Month Day Qty Amount Item Customer
0 2003 9 1 30.0 220.80 N2719 3110361
1 2003 9 1 1.0 75.17 X1046 3126034
2 2003 9 1 240.0 379.20 D5853 0008933
3 2003 9 1 2112.0 2787.84 D5851 0008933
4 2003 9 1 3312.0 4371.84 D5851 0008933
...
...
<2.7M rows>
这是按年/月/日排序的交易数据,并捕获向哪个客户出售了哪个项目以及该次销售中的数量和金额。
由于我要按商品和客户分析时间序列,因此我对其应用了MultiIndex:
df.set_index(['Item', 'Customer', 'Year', 'Month', 'Day'], inplace=True, drop=True)
df.sortlevel(inplace=True)
这给了我一个很好排序的数据框,看起来像:
Item Customer Year Month Day Qty Amount
X1046 3126034 2003 9 1 1.0 75.17
< ... other transactions for X1046/3126034 item/customer combination ...>
3126035 2005 1 2 50.0 500.00
< ... other transactions for X1046/3126035 item/customer combination ...>
< ... 48 other customers for X1046 ...>
N2719 3110361 2003 9 1 30.0 220.80
< ... other transactions for N2719/3110361 item/customer combination ...>
3110362 2004 9 10 9.0 823.00
< ... other transactions for N2719/3110362 item/customer combination ...>
< ... 198 other customers for N2719 ... >
< ... 6998 other items ... >
如您所见,由于我有7,000个不同的商品,每个商品可以有数十个或数百个客户,因此我只想关注那些拥有大量客户群的商品。数据集中有很多物品可能是过去某个时候有1位客户购买的,并且可能已经停产,等等。
因此,请使用以下内容获取按客户数量排序的商品:
item_by_customers = df.reset_index().groupby('Item')['Customer'].nunique().sort_values(ascending=False)
哪个给我的商品是熊猫系列按顾客数量排序的
Item
N2719 200
X1046 50
<... 6998 other rows ...>
现在,我想将此排序顺序应用于我的DataFrame,因此首先显示项N2719的数据(保留其中的MultiIndex的所有级别),然后显示X1046,依此类推。
我无法弄清楚如何做到这一点。
这是我到目前为止尝试过的:
sorted_data = df.set_index(item_by_customers.index)
< ... gives me ValueError: Length mismatch: Expected axis has 2.7M elements, new values have 7000 elements ...>
我可以看到为什么会出现此错误,因为索引中有7,000个项目,而DataFrame中有2.7M行。
我也尝试过重新索引:
sorted_data = df.reindex(index=item_by_customers.index, columns=['Item'])
< ... gives me Exception: cannot handle a non-unique multi-index! ...>
还有一个sort_index()
,其本质上是根据索引列的值而不是其他条件对索引列进行排序。
我正在寻找有关如何将item_by_customers.index
应用于DataFrame的一些指导,因此我得到一个看起来像这样的DataFrame:
Item Customer Year Month Day Qty Amount
N2719 3110361 2003 9 1 30.0 220.80
< ... other transactions for N2719/3110361 item/customer combination ...>
3110362 2004 9 10 9.0 823.00
< ... other transactions for N2719/3110362 item/customer combination ...>
< ... 198 other customers for N2719 ... >
X1046 3126034 2003 9 1 1.0 75.17
< ... other transactions for X1046/3126034 item/customer combination ...>
3126035 2005 1 2 50.0 500.00
< ... other transactions for X1046/3126035 item/customer combination ...>
< ... 48 other customers for X1046 ...>
< ... 6998 other items ... >
答案 0 :(得分:1)
transform
df.assign(nu=df.groupby('Item').Customer.transform('nunique')) \
.sort_values(['nu', 'Item'], ascending=[False, True])
答案 1 :(得分:0)
这是您如何实现所需的东西:
import pandas as pd
df = pd.DataFrame({
'Item':['X1046','X1046','N2719','N2719','N2719'],
'Customer':['3126034','3126035','3110361','3110362','3110363'],
'Year':[2003,2005,2003,2004,2004],
'Month':[9,1,9,9,9],
'Day':[1,2,1,10,10],
'Qty':[1,50,30,9,9],
'Amount':[75.17,500,220,823,823]
})
df.set_index(['Item', 'Customer', 'Year', 'Month', 'Day'], inplace=True, drop=True)
df.sort_index(inplace=True)
item_by_customers = df.reset_index().groupby('Item')['Customer'].nunique().sort_values(ascending=False).rename('Unique_Customers')
df = df.join(item_by_customers, on='Item').sort_values('Unique_Customers', ascending=False)
print(df)
这给出的输出为:
Qty Amount Unique_Customers
Item Customer Year Month Day
N2719 3110361 2003 9 1 30 220.00 3
3110362 2004 9 10 9 823.00 3
3110363 2004 9 10 9 823.00 3
X1046 3126034 2003 9 1 1 75.17 2
3126035 2005 1 2 50 500.00 2
因此,基本策略是将唯一客户数作为一列添加到原始数据框,然后根据需要进行排序。