我如何优化这个多数投票



我有以下代码对数据框架中的数据进行多数投票:

def vote(df, systems):
test = df.drop_duplicates(subset=['begin', 'end', 'case', 'system'])
n = int(len(systems)/2)
data = []

for row in test.itertuples():
# get all matches
fx = test.loc[(test.begin == row.begin) & (test.end == row.end) & (test.case == row.case)]
fx = fx.loc[fx.system.isin(systems)]
# keep if in a majority of systems   
if len(set(fx.system.tolist())) > n:
data.append(fx)

out = pd.concat(data, axis=0, ignore_index=True)
out = out.drop_duplicates(subset=['begin', 'end', 'case'])

return out[['begin', 'end', 'case']]  

数据如下:

systems = ['A', 'B', 'C', 'D', 'E']
df = begin,end,system,case
0,9,A,0365
10,14,A,0365
10,14,B,0365
10,14,C,0365
28,37,A,0366
38,42,A,0366
38,42,B,0366
53,69,C,0366
56,60,B,0366
56,60,C,0366
56,69,D,0366
64,69,E,0366
83,86,B,0367

期望的输出应该是:

out = begin,end,case
10,14,0365
56,69,0366

如果期望的元素begin, end, case出现在大多数系统中,我们将它们累加并作为数据帧返回。

该算法工作得很好,但由于其中有数十万行,因此需要相当长的时间来处理。

我能想到的一个优化,但不确定如何实现是在itertuples迭代中:如果,对于过滤器集begin, end, case的第一个实例,在

中有匹配
fx = test.loc[(test.begin == row.begin) & (test.end == row.end) & (test.case == df.case) & (fx.system.isin(systems))]

那么,不迭代itertuples可迭代对象中与此过滤器匹配的其他行将是有益的。例如,对于10,14,A,0365的第一个实例,不需要检查接下来的两行,因为它们已经被计算过了。然而,由于可迭代对象已经固定,我无法跳过我能想到的这些。

移动到codereview…(不希望删除它,失去信誉点!)

我猜这就是你要找的,

import pandas as pd
from io import StringIO
#Preprocessing(ignore)
data = StringIO('''
0,9,A,0365
10,14,A,0365
10,14,B,0365
10,14,C,0365
28,37,A,0366
38,42,A,0366
38,42,B,0366
53,69,C,0366
56,60,B,0366
56,60,C,0366
56,69,D,0366
64,69,E,0366
83,86,B,0367
''')
systems = ['A', 'B', 'C', 'D', 'E']
df = pd.read_csv(data,names=['begin','end','system','case'])
df_test = df.drop_duplicates(subset=['begin', 'end', 'case', 'system'])[df['system'].isin(systems)]
n = int(len(systems)/2)
out = df_test.groupby(['begin']).agg({
'end':'max',
'case':'max',
'system': 'count'
}).reset_index()
out[out['system'] > n][['begin', 'end', 'case']]

输出:

begin   end case
1   10  14  365
5   56  69  366

相关内容

  • 没有找到相关文章

最新更新