首页 > 解决方案 > pandas - 从所有可能的列组合中创建一个 df

问题描述

我有这个熊猫数据框:

df = pd.DataFrame([['cat1', 1], ['cat2', 1], ['cat3', 2],
               ['cat1', 3]], columns=['category',
              'number'])

df
Out[32]: 
  category  number
0     cat1       1
1     cat2       1
2     cat3       2
3     cat1       3

第一列代表客户购买的产品类别。第二个代表与购买同一客户相关的数字。所以这个客户进行了 3 次购买。我想重塑表格,以便让该客户在第一次购买时购买的类别的所有组合,然后是第二次和第三次购买以及计算组合数量的新列:

      1     2     3  count
0  cat1  cat3   NaN      1
1  cat2  cat3   NaN      1
2  cat1  cat3  cat1      1
3  cat2  cat3  cat1      1 

我试图像这样旋转它:

df.pivot(columns='nb_achat', values='category')

但由于组合,它不起作用。你有办法做到这一点吗?

目标是了解客户第一次购买什么,然后第二次购买,以及有多少客户在购买 1 和 2 中购买了同一类别(例如)

编辑:这里是结果的一个例子

结果示例

标签: pythonpandas

解决方案


df = pd.DataFrame([['cat1', 1], ['cat2', 1], ['cat3', 2],
               ['cat1', 3]], columns=['category',
              'number'])

from itertools import product
result_items = []
product_numbers = df.number.sort_values().unique()
product_numbers = product_numbers[product_numbers >= 2]

# get all the combinations of results for all the product numbers
for number in product_numbers:

    purchase_history = []
    for hist in range(1, number+1):
        purchase_history.append(df.category[df.number == hist].tolist())

    for item in product(*purchase_history):

        item_store = {}
        for i in range(1, number+1):
            item_store[i] = item[i-1]

        result_items.append(item_store)

# put them all into a dataframe
results = pd.DataFrame(result_items)
results.fillna(0, inplace=True)
# get the counts of all history
results = results.groupby(results.columns.tolist()).size().reset_index(name='count')
# fix the NaN values
results.where(results!=0, np.nan, inplace=True)
print(results)

结果是:

      1     2     3  count
0  cat1  cat3   NaN      1
1  cat1  cat3  cat1      1
2  cat2  cat3   NaN      1
3  cat2  cat3  cat1      1

这个itertools解决方案不是特别优雅。我很想看看是否有人可以在没有那个凌乱的 for 循环的情况下做到这一点!


推荐阅读