【问题标题】:Python itertools combinations on objects对象上的 Python itertools 组合
【发布时间】: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 exampleHow to Ask 以及该页面上的其他链接。
  • 现在好点了吗?
  • 你想要的输出是什么?您想要将薪水与姓名连接起来(即,Rahul 总是有 20000),还是想要(姓名、薪水、姓名、薪水)的组合(即,有些项目 Rahul 有 20000、30000 和 40000)?
  • 请修正您的代码缩进。

标签: python python-3.x pandas combinations itertools


【解决方案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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多