优化循环从基于另一个字段的字段中提取子字符串

时间:2015-08-01 20:24:12

标签: python performance optimization pandas

我正在处理大型数据集(4百万乘4)。第一列是名称标识符,许多行具有相同的名称。第二列是一个位置,从-6开始并一直向上直到满足新的标识符,然后它再次开始计数。第三列是随机数,在这里不重要。第四列是一长串数字,如长条形码。数据看起来有点像这样:

YKLOI    -6    01    123   #puts 1st triplet in position -6
YKLOI    -5    25    456   #puts 2nd triplet in position -5
YKLOI    -4    05    789   #puts 3rd triplet in position -4
YKLOI    -3    75    012   #puts 4th triplet in position -3
YKLOI    -2    83    345                ...
YKLOI    -1    05    678
YKLOI     0    34    901
YKLOI     1    28    234   #puts last triplet in the last position
YKLJW    -6    87    569   #puts 1st triplet in position -6
YKLJW    -5    87    845   #puts 2nd triplet in position -5
...

我想让它看起来像这样:

import pandas as pd

#imports data
d = pd.read_csv('INPUT_FILE', sep='\t') 

#acknowledges that data was imported
print "Import Okay" 

#sets output path
output='OUTPUT_FILE' 

#loops from the first row till the end
for z in xrange(0,len(d)-1): 

    #goes to the fourth column, split the content every 3 characters and creates 
    #a list of these triplets.
    mop=map(''.join, zip(*[iter(d.loc[z][3])]*3)) 

    #substitutes the content of the fourth column in the z line by the triplet in 
    #the z+6 positon
    d.ix[z,3] = mop[int(d.loc[z][1])+6]

    #writes the new z line into the output file
    d.loc[[z]].to_csv(output, sep='\t', header=False, index=False, mode='a')

#acknowledges that the code is through
print "Done"

第四列中的长度变化很大,但第二列上的数字总是按顺序排列。

下面的代码是我得到的实际上正在完成工作的代码,但它需要永远这样做。截至目前,它已经运行了近18个小时,而且几乎没有超过100万。

我尝试了一些替代方案,例如只有在连续行的第一列中的名称不同时才构建映射,但这只会在其中添加一个语句并使代码更慢。

是否有人建议如何改善此任务的效果?

ActiveRecord::Base.table_name=

1 个答案:

答案 0 :(得分:4)

开始时有两个简单的更改。一,不要逐步编写输出文件,这会增加很多不必要的开销,而且是目前为止最大的问题。

其次,你似乎正在经历很多步骤来取出三胞胎。这样的事情会更有效率,.apply会消除一些循环开销。

def triplet(row):
    loc = (row[1] + 6) * 3
    return row[3][loc:loc+3]

d[3] = d.apply(triplet, axis=1)

# save the whole file once
d.to_csv(output2, sep='\t', header=False, index=False)