使用 pandas groupby 查找一起购买的商品的每周组合
Finding weekly combinations of items bought together using pandas groupby
我有一个 df
:
date category subcategory order_id product_id branch
2021-05-04 A aa 10 5 web
2021-06-04 A dd 10 2 web
2021-05-06 B aa 18 3 shop
2021-07-06 A aa 50 10 web
2021-07-06 C cc 10 15 web
2021-07-05 A ff 101 30 shop
2021-10-04 D aa 100 15 shop
我想回答一个问题哪些项目类别和子类别是一起购买的 每个分支类型每周一次。我正在考虑将 order_ids
分组并将 category & subcategory
聚合为 list
,如下所示:
a = (df.set_index('date')
.groupby(['order_id','branch'])
.resample('W-MON', label = 'left')
.agg({'category':list, 'subcategory':list}))
哪个 returns :
category subcategory
order_id branch date [A, A, A] [aa, dd, aa]
10 web 2021-05-04 ... ...
18 shop ...
50 web
100 web
101 shop
我正在尝试建立一个结构来显示 categories
和 subcategories
每 branch
每周购买的每个变体的频率,类似于此:
branch date
2021-05-04 2021-05-011
...
web category 3, [A, A, A]
2, [A, A]
2, [A, A, B, B]
subcategory 5, [aa, dd, aa]
4, [dd, aa]
1, [dd]
shop category 3, [A, A, A]
2, [A, A]
2, [A, A, B, B]
subcategory 5, [aa, dd, aa]
4, [dd, aa]
1, [dd]
其中列表前的数字表示categories
和subcategories
的某些组合在同一订单中被购买的次数。我不确定如何实现这样的结构或类似的结构来显示 branch
的每周组合频率。顺序中 product_id
的顺序无关紧要,因为最终篮子相同。
所以目标是查看 categories, subcategories & product_ids
每周以相同订单购买的频率。因此,如果 2 个不同的订单具有相同的产品,则汇总结果将显示 2, [A,B] [aa, bb] [5, 2]
,其中列表包含类别、子类别和 product_id 组合。
这就是你需要的:
import pandas as pd
import numpy as np
from datetime import timedelta
from datetime import datetime as dt
# df=pd.read_excel('demo.xlsx')
df['date']=pd.to_datetime(df['date'])
df['date']=df['date'].dt.strftime('%Y-%m-%d')
df['date']=pd.to_datetime(df['date'])
df['year_week'] = df['date'].dt.strftime('%Y_%U')
df['orderid_year_week']=df['order_id'].astype(str)+'_'+df['year_week']
df=df.sort_values(['category', 'subcategory','product_id'], ascending=[True, True,True])
a = (df.set_index('orderid_year_week')
.groupby(['year_week','order_id'],sort=False)
.agg({'category':list, 'subcategory':list,'product_id':list})).reset_index()
a['category'] =a['category'].astype(str)
a['subcategory'] =a['subcategory'].astype(str)
a['product_id'] =a['product_id'].astype(str)
df=pd.pivot_table(a,index=['year_week','category','subcategory','product_id'],values='product_id',aggfunc='count').reset_index()
df.rename({'order_id':'count'},axis=1,inplace=True)
输出如下所示(我在您提供的示例之上添加了更多条目):
您的解释中有些地方crystal不清楚。但如果这完全回答了您的问题,请告诉我。
这是一个很好的问题。
您知道名为“Apriori 算法”的数据挖掘技术吗?
您正在做的是挖掘关联规则,通常用于建立对一起购买的事物的理解。
我强烈推荐使用 mlxtend 中的频繁项集包。这也将允许您通过一起购买的项目的 'support' 指标来控制显着性水平,而不是需要通过您定制的解决方案来发现这一点。
dataset = [['Milk', 'Onion', 'Nutmeg', 'Kidney Beans', 'Eggs', 'Yogurt'],
['Dill', 'Onion', 'Nutmeg', 'Kidney Beans', 'Eggs', 'Yogurt'],
['Milk', 'Apple', 'Kidney Beans', 'Eggs'],
['Milk', 'Unicorn', 'Corn', 'Kidney Beans', 'Yogurt'],
['Corn', 'Onion', 'Onion', 'Kidney Beans', 'Ice cream', 'Eggs']]
import pandas as pd
from mlxtend.preprocessing import TransactionEncoder
te = TransactionEncoder()
te_ary = te.fit(dataset).transform(dataset)
df = pd.DataFrame(te_ary, columns=te.columns_)
df
http://rasbt.github.io/mlxtend/user_guide/frequent_patterns/apriori/
from mlxtend.frequent_patterns import apriori
apriori(df, min_support=0.6)
apriori(df, min_support=0.6, use_colnames=True)
我有一个 df
:
date category subcategory order_id product_id branch
2021-05-04 A aa 10 5 web
2021-06-04 A dd 10 2 web
2021-05-06 B aa 18 3 shop
2021-07-06 A aa 50 10 web
2021-07-06 C cc 10 15 web
2021-07-05 A ff 101 30 shop
2021-10-04 D aa 100 15 shop
我想回答一个问题哪些项目类别和子类别是一起购买的 每个分支类型每周一次。我正在考虑将 order_ids
分组并将 category & subcategory
聚合为 list
,如下所示:
a = (df.set_index('date')
.groupby(['order_id','branch'])
.resample('W-MON', label = 'left')
.agg({'category':list, 'subcategory':list}))
哪个 returns :
category subcategory
order_id branch date [A, A, A] [aa, dd, aa]
10 web 2021-05-04 ... ...
18 shop ...
50 web
100 web
101 shop
我正在尝试建立一个结构来显示 categories
和 subcategories
每 branch
每周购买的每个变体的频率,类似于此:
branch date
2021-05-04 2021-05-011
...
web category 3, [A, A, A]
2, [A, A]
2, [A, A, B, B]
subcategory 5, [aa, dd, aa]
4, [dd, aa]
1, [dd]
shop category 3, [A, A, A]
2, [A, A]
2, [A, A, B, B]
subcategory 5, [aa, dd, aa]
4, [dd, aa]
1, [dd]
其中列表前的数字表示categories
和subcategories
的某些组合在同一订单中被购买的次数。我不确定如何实现这样的结构或类似的结构来显示 branch
的每周组合频率。顺序中 product_id
的顺序无关紧要,因为最终篮子相同。
所以目标是查看 categories, subcategories & product_ids
每周以相同订单购买的频率。因此,如果 2 个不同的订单具有相同的产品,则汇总结果将显示 2, [A,B] [aa, bb] [5, 2]
,其中列表包含类别、子类别和 product_id 组合。
这就是你需要的:
import pandas as pd
import numpy as np
from datetime import timedelta
from datetime import datetime as dt
# df=pd.read_excel('demo.xlsx')
df['date']=pd.to_datetime(df['date'])
df['date']=df['date'].dt.strftime('%Y-%m-%d')
df['date']=pd.to_datetime(df['date'])
df['year_week'] = df['date'].dt.strftime('%Y_%U')
df['orderid_year_week']=df['order_id'].astype(str)+'_'+df['year_week']
df=df.sort_values(['category', 'subcategory','product_id'], ascending=[True, True,True])
a = (df.set_index('orderid_year_week')
.groupby(['year_week','order_id'],sort=False)
.agg({'category':list, 'subcategory':list,'product_id':list})).reset_index()
a['category'] =a['category'].astype(str)
a['subcategory'] =a['subcategory'].astype(str)
a['product_id'] =a['product_id'].astype(str)
df=pd.pivot_table(a,index=['year_week','category','subcategory','product_id'],values='product_id',aggfunc='count').reset_index()
df.rename({'order_id':'count'},axis=1,inplace=True)
输出如下所示(我在您提供的示例之上添加了更多条目):
您的解释中有些地方crystal不清楚。但如果这完全回答了您的问题,请告诉我。
这是一个很好的问题。 您知道名为“Apriori 算法”的数据挖掘技术吗?
您正在做的是挖掘关联规则,通常用于建立对一起购买的事物的理解。
我强烈推荐使用 mlxtend 中的频繁项集包。这也将允许您通过一起购买的项目的 'support' 指标来控制显着性水平,而不是需要通过您定制的解决方案来发现这一点。
dataset = [['Milk', 'Onion', 'Nutmeg', 'Kidney Beans', 'Eggs', 'Yogurt'],
['Dill', 'Onion', 'Nutmeg', 'Kidney Beans', 'Eggs', 'Yogurt'],
['Milk', 'Apple', 'Kidney Beans', 'Eggs'],
['Milk', 'Unicorn', 'Corn', 'Kidney Beans', 'Yogurt'],
['Corn', 'Onion', 'Onion', 'Kidney Beans', 'Ice cream', 'Eggs']]
import pandas as pd
from mlxtend.preprocessing import TransactionEncoder
te = TransactionEncoder()
te_ary = te.fit(dataset).transform(dataset)
df = pd.DataFrame(te_ary, columns=te.columns_)
df
http://rasbt.github.io/mlxtend/user_guide/frequent_patterns/apriori/
from mlxtend.frequent_patterns import apriori
apriori(df, min_support=0.6)
apriori(df, min_support=0.6, use_colnames=True)