python - 计算熊猫数据框中的匹配组合
问题描述
我需要为以下问题找到更有效的解决方案:
给定的是一个数据框,每行有 4 个变量。我需要找到 8 个元素的列表,其中包含最大行数中每行的所有变量。
一个可行但非常缓慢的解决方案是创建第二个数据帧,其中包含所有可能的组合(基本上是没有重复的排列)。然后遍历每个组合并将其与初始数据帧进行比较。计算解决方案的数量并将其添加到第二个数据帧中。
import numpy as np
import pandas as pd
from itertools import combinations
df = pd.DataFrame(np.random.randint(0,20,size=(100, 4)), columns=list('ABCD'))
df = 'x' + df.astype(str)
listofvalues = df['A'].tolist()
listofvalues.extend(df['B'].tolist())
listofvalues.extend(df['C'].tolist())
listofvalues.extend(df['D'].tolist())
listofvalues = list(dict.fromkeys(listofvalues))
possiblecombinations = list(combinations(listofvalues, 6))
dfcombi = pd.DataFrame(possiblecombinations, columns = ['M','N','O','P','Q','R'])
dfcombi['List'] = dfcombi.M.map(str) + ',' + dfcombi.N.map(str) + ',' + dfcombi.O.map(str) + ',' + dfcombi.P.map(str) + ',' + dfcombi.Q.map(str) + ',' + dfcombi.R.map(str)
dfcombi['Count'] = ''
for x, row in dfcombi.iterrows():
comparelist = row['List'].split(',')
pointercounter = df.index[(df['A'].isin(comparelist) == True) & (df['B'].isin(comparelist) == True) & (df['C'].isin(comparelist) == True) & (df['D'].isin(comparelist) == True)].tolist()
row['Count'] = len(pointercounter)
我认为必须有一种方法可以避免 for - 循环并用一些指针替换它,我只是不知道如何。
谢谢!
解决方案
您的代码可以重写为:
# working with integers are much better than strings
enums, codes = df.stack().factorize()
# encodings of df
s = [set(x) for x in enums.reshape(-1,4)]
# possible combinations
from itertools import combinations, product
possiblecombinations = np.array([set(x) for x in combinations(range(len(codes)), 6)])
# count the combination with issubset
ret = [0]*len(possiblecombinations)
for a, (i,b) in product(s, enumerate(possiblecombinations)):
ret[i] += a.issubset(b)
# the combination with maximum count
max_combination = possiblecombinations[np.argmax(ret)]
# in code {0, 3, 4, 5, 17, 18}
# and in values:
codes[list(max_combination)]
# Index(['x5', 'x15', 'x12', 'x8', 'x0', 'x6'], dtype='object')
与您花费大约 1.5 分钟的代码相反,所有这些花费了大约 2 秒。
推荐阅读
- javascript - 如何在纯 TypeScript 项目中修复“ReferenceError:未定义导出”?
- bash - 将 DateTime 转换为 bash 中的时间戳
- html - HTML / CSS 创建一个巨大的下拉菜单
- excel - 将范围从工作表复制到可视化数据的主工作表
- javascript - 如何在 Angular 中获取数据模型的类名?
- momentjs - 如何获取工作日的列表名称?
- amazon-s3 - boto3 put metadata清空对象内容
- botframework - Directline/Web 聊天频道错误:HTTP 状态码 Forbidden
- reactjs - 如何在 React Native 中创建可拖动组件?
- oauth-2.0 - OneLogin:以编程方式获取 JWT 令牌