熊猫搜索速度/性能/效率

时间:2016-12-28 17:40:06

标签: python arrays performance loops pandas

ID  outcome Source_doc
23145   A   ARR
23145   A   CRE
23145   B   ARR
23145   C   CRE
23456   B   ARR
23456   B   CRE
来自ARR的ID#145具有[A,B]结果。来自CRE的ID#145具有[A,C]结果。您可以在下方看到我将ID#145放入' not_same_list'。我的数据集包括445,000行。我执行的过程每100行需要21秒。所以这需要7个多小时!

此循环中最慢的部分是什么?

我是否最有效地执行Pandas搜索?

iterrows()会更快吗?

编辑:关于预期产出的好点。我实际上只是期待一份ID列表。如果AAR_list和CRE_list不相同,我想标记该ID并将其放入列表(not_same_list)。所以,我正在寻找[145,178,...,989,(任何结果不符合其来源文档的ID)]

not_same_list = []
total_search_start_time = time.time()
tick = 0
for IDs in uniq_IDs['ID'].unique():
    #Isolate rows by their ID and source doc
    sco_ARR = uniq_IDs['outcome'][uniq_IDs['ID'] == IDs][uniq_IDs['Source_Doc'] == 'ARR']
    sco_CRE = uniq_IDs['outcome'][uniq_IDs['ID'] == IDs][uniq_IDs['Source_Doc'] == 'CRE']
    #Remove duplicates 
    ARR_list = set(sco_ARR.values.tolist())
    CRE_list = set(sco_CRE.values.tolist())

#Check to see if outcomes match between source docs
if ARR_list != CHRI_list:
    not_same_list.append(IDs)       

if str(tick)[-2:] == '00':
    print ('The last {} rows have taken {} seconds...'.format(tick,round(time.time()-total_search_start_time,2)))
    tick += 1 
else:
    tick += 1

print ('The last {} rows have taken {} seconds...'.format(tick,round(time.time()-total_search_start_time,2))) 
print (not_same_list)

如果有人能为这个问题做出更好的表格,请执行以下操作:

2 个答案:

答案 0 :(得分:4)

重写你的for循环的pandas惯用方法是:

(df.groupby(['ID', 'Source_doc'])['outcome'].apply(set)
   .groupby(level=0).nunique()[lambda x: x==2].index)

# Int64Index([23145], dtype='int64', name='ID')

你的for循环速度慢的原因是因为你正在处理未排序的数据,那就是你按ID对数据框进行子集化,然后按Source_doc进行子集化您可以通过矢量扫描方式多次浏览数据帧(取决于您拥有多少个唯一ID和Source_doc);使用groupby()可以避免这个问题,因为它按组变量对数据帧进行排序,然后按块处理它;

要了解有关此理念的更多信息,请查看this answer

答案 1 :(得分:2)

我会尝试这样的事情

d1 = df.groupby(['ID', 'Source_doc']).outcome.apply(set).unstack()
print(d1)

Source_doc     ARR     CRE
ID                        
23145       {B, A}  {A, C}
23456          {B}     {B}

然后检查是否相等

d1.ARR == d1.CRE

ID
23145    False
23456     True
dtype: bool

您可以过滤d1的索引以获取not_equal ID

列表
d1.index[d1.ARR != d1.CRE]

Int64Index([23145], dtype='int64', name='ID')
相关问题