Ema*_*mac 2 python python-itertools dataframe pandas
我试图找出一种方法来确定 DataFrame 中低于预算的所有可能的行组合,所以假设我有一个这样的数据帧:
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
Run Code Online (Sandbox Code Playgroud)
数据
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
Run Code Online (Sandbox Code Playgroud)
我想找到在特定预算下我可以购买的每一种组合,假设这个例子是 35 美元,而每种类型只得到一种。我想获得一个由每个组合的行组成的新数据框,这些组合适用于其自己的列中的每个项目。
我试图使用 itertools.product 来做到这一点,但这可以组合和添加列,但我真正需要做的是根据另一列中的值组合和添加特定列。我现在有点难住了。
谢谢你的帮助!
这里有一种使用方法 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)])
Run Code Online (Sandbox Code Playgroud)
输出包含满足 $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
Run Code Online (Sandbox Code Playgroud)
有多少种方法可以满足 35 美元的预算?
df_groups['grp'].nunique()
Run Code Online (Sandbox Code Playgroud)
输出:
258
Run Code Online (Sandbox Code Playgroud)
细节:
这里使用了一些技巧/方法。首先,我们使用数据框的索引来创建行组或项目组powerset。接下来,我们使用enumerate来标识每个组,并使用assignenumerate 中的组号在数据框中创建一个新列。
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())])
Run Code Online (Sandbox Code Playgroud)
几组?
df_groups['grp'].nunique()
62
Run Code Online (Sandbox Code Playgroud)
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))])
Run Code Online (Sandbox Code Playgroud)
几组?
df_groups['grp'].nunique()
21
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1052 次 |
| 最近记录: |