pandas 如何统计Python DataFrame中每月在组合类别中重叠的唯一customer_id的数量?

e3bfsja2  于 2023-09-29  发布在  Python
关注(0)|答案(1)|浏览(88)

我正在使用一个包含金融交易信息的Python DataFrame。DataFrame具有以下相关列:customer_id、date、product_type。每一行表示客户在特定月份进行的交易,product_type表示交易类别。
我的目标是计算每个月在组合类别中重叠的唯一customer_id值的数量。换句话说,我想知道有多少客户在一个特定的月份中有超过一个类别的交易。
例如,如果在2022年6月,“类别A”中有10个唯一的customer_id值,“类别B”中有6个唯一的customer_id值,那么我如何计算出该月在这两个类别中有多少个customer_id值重叠?
输入表如下所示:
| 客户ID|分支ID|产品类型|日期|
| --|--|--|--|
| 客户ID 1| Branch1| A类|2022-06-30 22:47:35|
| 客户ID 2| Branch2| B类|2022-06-30 22:43:21|
| 客户ID 3| Branch3| A类|2022-06-30 22:43:04|
| 客户ID 4| Branch1| C类|2022-06-30 22:42:42|
| 客户ID 5| Branch2| B类|2022-06-30 22:31:03|
| 客户ID 6| Branch3| A类|2022-06-30 22:47:35|
| 客户ID 7| Branch1| D类|2022-06-30 22:43:21|
| 客户ID 8| Branch2| C类|2022-06-30 22:43:04|
| 客户ID 9| Branch3| E类|2022-06-30 22:42:42|
| 客户ID 10| Branch1| B类|2022-06-30 22:31:03|
下面是我试图解决这个问题的部分代码:

import pandas as pd
from itertools import combinations

# DataFrame df with transaction information

categories = ["Category A", "Category B", "Category C", "Category D", "Category E"]

combined_tables = pd.DataFrame()

for i in range(1, len(categories) + 1):
    for combo in combinations(categories, i):
        combo_name = ' & '.join(combo)
        filtered_df = df[df['product_type'].isin(combo)]
        
        # Count how many customer_ids overlap in the same category in each month
        grouped = filtered_df.groupby(['year', 'month', 'product_type'])['customer_id'].nunique().reset_index()
        grouped.rename(columns={'customer_id': combo_name}, inplace=True)
        
        if combined_tables.empty:
            combined_tables = grouped
        else:
            combined_tables = combined_tables.merge(grouped, on=['year', 'month', 'product_type'], how='left')

我希望获得一个DataFrame,它显示每个月在组合类别中重叠的唯一customer_id值的计数。结果应该包含年份、月份、类别组合的列,并且值应该表示唯一customer_id值的计数。
我期待一个像这样的塔布拉:
| 年|月|A类|B类|C类|A类和B类|A类和C类|B类和C类|A类& B类& C类|
| --|--|--|--|--|--|--|--|--|
| 2022 | 6 | 10 | 6 | 8 | 2 | 5 | 3 | 1 |
| 2022 | 7 | 7 | 9 | 4 | 3 | 2 | 1 | 0 |
| 2022 | 8 | 6 | 5 | 7 | 2 | 4 | 3 | 1 |
| 2022 | 9 | 9 | 4 | 8 | 1 | 3 | 2 | 0 |
| 2022 | 10 | 8 | 7 | 6 | 2 | 2 | 1 | 0 |
| 2022 | 11 | 7 | 8 | 5 | 1 | 2 | 1 | 0 |
| 2022 | 12 | 8 | 9 | 4 | 2 | 1 | 1 | 0 |
| 2023 | 1 | 9 | 6 | 7 | 1 | 2 | 1 | 0 |
| 2023 | 2 | 7 | 5 | 8 | 1 | 3 | 2 | 0 |
| 2023 | 3 | 8 | 4 | 9 | 2 | 4 | 3 | 1 |
| 2023 | 4 | 6 | 7 | 6 | 2 | 2 | 1 | 0 |
| 2023 | 5 | 5 | 6 | 7 | 1 | 3 | 2 | 0 |
| 2023 | 6 | 6 | 5 | 8 | 2 | 4 | 3 | 1 |
| 2023 | 7 | 7 | 4 | 9 | 1 | 2 | 1 | 0 |
类别之间的所有可能组合

ulydmbyx

ulydmbyx1#

关于输入字典框的信息并不多,但我试图为您提供一个使用嵌套字典以及len()set()函数的想法。请参见下文。

data={}
for category in set(df.product_type):
    data[category]={}
    for y in set(df.year):
        data[category][y]={}
        for m in set(df.month):
            data[category][y][m]=[]
for row in range(len(df)):
    category=df.iat[row,list(df.columns).index('product_type')]
    y=df.iat[row,list(df.columns).index('year')]
    m=df.iat[row,list(df.columns).index('month')]
    cid=df.iat[row,list(df.columns).index('customer_id')]
    data[category][y][m]+=[cid]

header=['year','month']+list(set(df.product_type))
rows=[]
for y in set(df.year):
    for m in set(df.month):
        l=[y,m]
        for c in header[2:]:
            l+=[len(set(data[c][y][m]))]
        rows+=[l]
pd.DataFrame(data=rows,columns=header)

它肯定可以改进和优化,但它工作得很好。我在一个有100,000行的样本输入上运行了它,在我的电脑上花了大约8秒。希望这对你有帮助:)

相关问题