对象上的 Python itertools 组合

Posted

技术标签:

【中文标题】对象上的 Python itertools 组合【英文标题】:Python itertools combinations on objects 【发布时间】:2019-01-07 23:09:25 【问题描述】:

python itertools 组合库可以用于对象而不是列表吗?

例如,我如何在以下数据上使用它?

Rahul - 20,000 - Mumbai

Shivani - 30,000 - Mumbai

Akash - 40,000 - Bangalore

我想要姓名和组合工资值的所有可能组合。

如何使用 combinations 执行此操作? 假设使用pd.read_csv 读取数据并存储。

到目前为止的代码 -

import pandas as pd
import itertools
df = pd.read_csv('stack.csv')

print (df)

for L in range(0, len(df)+1):
    for subset in itertools.combinations(df['Name'], L):
        print (subset)

输出

      Name  Salary       City
0    Rahul   20000     Mumbai
1  Shivani   30000     Mumbai
2    Akash   40000  Bangalore
()
('Rahul',)
('Shivani',)
('Akash',)
('Rahul', 'Shivani')
('Rahul', 'Akash')
('Shivani', 'Akash')
('Rahul', 'Shivani', 'Akash')

Process finished with exit code 0

如何将工资添加到这些组合中?

【问题讨论】:

您能打印 df.head(5) 以了解输入格式吗? 欢迎来到 SO。请花时间阅读minimal reproducible example、How to Ask 以及该页面上的其他链接。 现在好点了吗? 你想要的输出是什么?您想要将薪水与姓名连接起来(即,Rahul 总是有 20000),还是想要(姓名、薪水、姓名、薪水)的组合(即,有些项目 Rahul 有 20000、30000 和 40000)? 请修正您的代码缩进。 【参考方案1】:

首先,获取您的索引:

idx = [j for i in range(1, len(df) + 1) for j in list(itertools.combinations(df.index, i))]
# [(0,), (1,), (2,), (0, 1), (0, 2), (1, 2), (0, 1, 2)]

获取每个组的数据框:

dfs = [df.iloc[list(i)] for i in idx]

最后,加入和求和:

out = [(', '.join(i.name.values), sum(i.salary.values)) for i in dfs]

输出:

[('Rahul', 20000),
 ('Shivani', 30000),
 ('Akash', 40000),
 ('Rahul, Shivani', 50000),
 ('Rahul, Akash', 60000),
 ('Shivani, Akash', 70000),
 ('Rahul, Shivani, Akash', 90000)]

如果你想把它作为一个数据框,这很简单:

df1 = pd.DataFrame(out, columns=['names', 'salaries'])

                   names  salaries
0                  Rahul     20000
1                Shivani     30000
2                  Akash     40000
3         Rahul, Shivani     50000
4           Rahul, Akash     60000
5         Shivani, Akash     70000
6  Rahul, Shivani, Akash     90000

要查询此数据框以找到最接近给定薪水的值,我们可以编写一个辅助函数:

def return_closest(val):
    return df1.iloc[(df1.salaries - val).abs().idxmin()]


>>> return_closest(55000)
names       Rahul, Shivani
salaries             50000
Name: 3, dtype: object

我故意将其分解,以便您了解每一步发生的情况。一旦您了解,您就可以将其组合成一个单行代码来创建您的数据框:

pd.DataFrame(
    [(', '.join(d.name.values), sum(d.salary.values))
    for i in [j for i in range(1, len(df) + 1)
    for j in list(itertools.combinations(df.index, i))]
    for d in [df.iloc[list(i)]]], columns=['names', 'salaries']
)

【讨论】:

你使用过join(i.name.values)的部分,我如何将它用于多个列?假设我希望将 City 包含在此结果中,我该如何重写这一行?【参考方案2】:

您可以使用zip 同时遍历两列,并使用列表推导生成输出数据框,例如:

df_ouput = pd.DataFrame( [[', '.join(subset), sum(salaries)] for L in range(1, len(df)+1)
                           for subset, salaries in zip(itertools.combinations(df['Name'], L),
                                                       itertools.combinations(df['Salary'], L))], 
                         columns = ['Names','Sum Salaries'])

你会得到:

                   Names  Sum Salaries
0                  Rahul         20000
1                Shivani         30000
2                  Akash         40000
3         Rahul, Shivani         50000
4           Rahul, Akash         60000
5         Shivani, Akash         70000
6  Rahul, Shivani, Akash         90000

【讨论】:

【参考方案3】:

这样怎么样?

nameList = list()
sumList = list()
for L in range(0, len(df)+1):
    for x in itertools.combinations(df['Name'], L):
        nameList.append(x)
    for y in itertools.combinations(df['Salary'], L):
        sumList.append(sum(y))

newDf = pd.DataFrame()
newDf['Names'] = nameList
newDf['Salary Sum'] = sumList

输出:

                     Names  Salary Sum
0                       ()           0
1                 (Rahul,)       20000
2               (Shivani,)       30000
3                 (Akash,)       40000
4         (Rahul, Shivani)       50000
5           (Rahul, Akash)       60000
6         (Shivani, Akash)       70000
7  (Rahul, Shivani, Akash)       90000

【讨论】:

以上是关于对象上的 Python itertools 组合的主要内容,如果未能解决你的问题,请参考以下文章

Python循环器-itertools

python模块分析之itertools

在 python 中使用组合对象

python值itertools模块

如何指定仅允许某些第一个组合的 itertools 排列?

Python:生成此组合的 itertools?