熊猫找到预算下的所有行的组合[英] Pandas find all combinations of rows under a budget

本文是小编为大家收集整理的关于熊猫找到预算下的所有行的组合的处理方法,想解了熊猫找到预算下的所有行的组合的问题怎么解决?熊猫找到预算下的所有行的组合问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

我正在尝试找出一种方法来确定数据框内的所有可能的行组合,因此,假设我有这样的数据框架:

data = [['Bread', 9, 'Food'], ['Shoes', 20, 'Clothes'], ['Shirt', 15, 'Clothes'], ['Milk', 5, 'Drink'], ['Cereal', 8, 'Food'], ['Chips', 10, 'Food'], ['Beer', 15, 'Drink'], ['Popcorn', 3, 'Food'], ['Ice Cream', 6, 'Food'], ['Soda', 4, 'Drink']]
df = pd.DataFrame(data, columns = ['Item', 'Price', 'Type'])
df

数据

Item       Price  Type
Bread      9      Food
Shoes      20     Clothes
Shirt      15     Clothes
Milk       5      Drink
Cereal     8      Food
Chips      10     Food
Beer       15     Drink
Popcorn    3      Food
Ice Cream  6      Food
Soda       4      Drink

我想找到我可以在特定预算下购买的所有组合,假设此示例的$ 35,而仅获取每种类型之一.我想获得一个由每个组合组成的新数据框,这些组合与其自己的列中的每个项目一起使用.

我试图使用itertools.products进行操作,但这可以组合和添加列,但是我真正需要做的就是将基于另一列中值的特定列组合并添加一个特定的列.我现在有点困难.

感谢您的帮助!

推荐答案

在这里使用powerset itertools配方的方式,pd.concat

from itertools import chain, combinations

def powerset(iterable):
    "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
    s = list(iterable)
    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

df_groups = pd.concat([df.reindex(l).assign(grp=n) for n, l in 
                       enumerate(powerset(df.index)) 
                       if (df.loc[l, 'Price'].sum() <= 35)])

输出一个符合$ 35条件的产品组的单个数据框架:

          Item  Price     Type  grp
0       Bread      9     Food    1
1       Shoes     20  Clothes    2
2       Shirt     15  Clothes    3
3        Milk      5    Drink    4
4      Cereal      8     Food    5
..        ...    ...      ...  ...
3        Milk      5    Drink  752
4      Cereal      8     Food  752
7     Popcorn      3     Food  752
8   Ice Cream      6     Food  752
9        Soda      4    Drink  752

这是多少方式来满足35美元的预算?

df_groups['grp'].nunique()

输出:

258

详细信息:

这里使用了几个技巧/方法.首先,我们使用dataFrame的索引使用powerset创建行组或项目组.接下来,我们使用enumerate来识别每个组,并使用assign在数据框中创建一个新的列,并从枚举中进行该组号.

修改以捕获每种类型中的一种:

df_groups = pd.concat([df.reindex(l).assign(grp=n) for n, l in 
                       enumerate(powerset(df.index)) 
                       if ((df.loc[l, 'Price'].sum() <= 35) & 
                           (df.loc[l, 'Type'].value_counts()==1).all())])

多少组?

df_groups['grp'].nunique()
62

完全适合每种类型:

df_groups = pd.concat([df.reindex(l).assign(grp=n) for n, l in 
                       enumerate(powerset(df.index)) 
                       if ((df.loc[l, 'Price'].sum() <= 35) & 
                           (df.loc[l, 'Type'].value_counts()==1).all()&
                           (len(df.loc[l, 'Type']) == 3))])

多少组?

df_groups['grp'].nunique()
21

本文地址:https://www.itbaoku.cn/post/1727836.html