对象上的 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 组合的主要内容,如果未能解决你的问题,请参考以下文章