所以我有2个文件,文件1有4列,有160000行数值数据,文件2有26列,有150000个数值数据。我想知道是否有办法匹配两个文件中相同的值并显示这种匹配的行。我正在尝试减少文件2中的行以匹配文件1的行数。
答案 0 :(得分:1)
我在这里做了一些假设:
这两个文件都没有有用的排序顺序,因此没有有效的方法来锁定步骤。
你有足够的内存用于一组160000个4元组的短字符串。
您可以按字符串而不是数字进行匹配(例如,您不会在文件1中使用“0013”而在文件2中使用“00013”并期望它们匹配)。如果没有,只需将每个line.split()
更改为int(col) for col in line.split()
即可。 (这也可能会减少内存使用量,但也可能会降低速度。无论如何,除非出现问题,否则通常会更好。)
您的格式只不过是以空格分隔的数字。如果它更复杂,请按照acjohnson55的建议使用csv
模块。
匹配列是文件2中的前四列,它们的顺序与文件1中的顺序相同。否则,您需要添加cols = cols[3], cols[14], cols[15], cols[1]
之类的内容。
如果这些都是很好的假设,那么这就是代码:
with open(path1, 'r') as f1:
data = set(tuple(line.split()) for line in f1)
with open(path2, 'r') as f2, open(outpath, 'w') as f3:
for line in f2:
cols = line.split()
if tuple(cols[:4]) in data:
f3.write(line + '\n')
答案 1 :(得分:1)
在我看来,您想要的是将文件1的每一行作为元组读取,可能使用csv
模块,并将每个元组添加到set。然后,对于文件2中的每一行,提取可能与文件1匹配的4列,并检查它们是否在集合中。如果是这样,请将该行写入新的输出文件。
答案 2 :(得分:0)
您可以使用我在回复之前问题时发布的技术,此处:How to vectorize a simple for loop in Python/Numpy
基本上,将这两个文件读入numpy数组,对两个数组进行排序,然后以lockstep进行迭代。其他人描述的基于散列的代码(元组集)几乎肯定会使用比这更多的内存:)哪一个更快,你必须尝试看看。
import numpy as np
def is_less(a, b):
# this ugliness is needed because we want to compare lexicographically same as np.lexsort(), from the last column backward
for i in range(len(a)-1, -1, -1):
if a[i]<b[i]: return True
elif a[i]>b[i]: return False
return False
def is_equal(a, b):
for i in range(len(a)):
if a[i] != b[i]: return False
return True
arr1 = np.fromfile('arr1.csv', sep=',')
arr2 = np.fromfile('arr2.csv', sep=',')
idx1 = np.lexsort( arr1.transpose() )
idx2 = np.lexsort( arr2.transpose() )
ii = 0
jj = 0
while ii < len(arr1) and jj < len(arr2):
a = arr1[ idx1[ii] , : ] # use all columns from this
b = arr2[ idx2[jj] , 0:4 ] # use only first four columns; or select the right ones with an appropriate slice
if is_equal( a, b ):
# do stuff with match
print "match found: arr1[%d]=%s arr2[%d]=%s" % ( idx1[ii], repr(a), idx2[jj], repr(b) )
ii += 1
jj += 1
elif is_less( a, b ):
ii += 1
else:
jj += 1