给定: 两个csv文件(每个1.8 MB):AllData_1,AllData_2。每个约有8,000行。每行包含8列。 [txt_0,txt_1,txt_2,txt_3,txt_4,txt_5,txt_6,txt_7,txt_8]
目标: 基于txt_0(或AllData_1 [0] == AllData_2)的匹配,比较这些单独行的后4列的内容。如果数据不相等,则根据不同的列将每组数据的整行放在一个列表中,并将列表保存到输出文件中。如果txt_0是一个数据集而不是另一个数据集,则将其直接保存到输出文件中。
示例:
AllData_1第x行包含:[a1,b2,c3,d4,e5,f6,g7,h8] AllData_2行y包含:[a1,b2,c33c,d44d,e5,f6,g7,h8]
程序将所有行x和y保存在与ListCol2和ListCol3对应的列表中。完成所有比较后,列表将保存到文件中。
如何更快地编写代码或将代码更改为更快的算法?
i = 0
x0list = []
y0list = []
col1_diff = col2_diff = col3a_diff = col3b_diff = col4_diff = []
#create list out of column 0
for y in AllData_2:
y0list.append(y[0])
for entry in AllData_1:
x0list.append(entry[0])
if entry[0] not in y0list:
#code to save the line to file...
for y0 in AllData_2:
if y0[0] not in x0list:
#code to save the line to file...
for yrow in AllData_2:
i+=1
for xrow in AllData_1:
foundit = 0
if yrow[0] == xrow[0] and foundit == 0 and (yrow[1] != xrow[1] or yrow[2] != xrow[2] or yrow[3] != xrow[3] or yrow[4] != xrow[4]):
if yrow[1] != xrow[1]:
col1_diff.append(yrow)
col1_diff.append(xrow)
foundit = 1
elif yrow[2] != xrow[2]:
col2_diff.append(yrow)
col2_diff.append(xrow)
foundit = 1
elif len(yrow[3]) < len(xrow[3]):
col3a_diff.append(yrow)
col3a_diff.append(xrow)
foundit = 1
elif len(yrow[3]) >= len(xrow[3]):
col3b_diff.append(yrow)
col3b_diff.append(xrow)
foundit = 1
else:
#col4 is actually a catch-all for any other differences between lines if [0]s are equal
col4_diff.append(yrow)
col4_diff.append(xrow)
foundit = 1
答案 0 :(得分:1)
如果您认为给定文件中没有两行在第0列中具有相同的数据,则可以使用少量dict
来显着改善您的代码。而不是行
x0list.append(entry[0])
y0list.append(y[0])
你会使用:
x0dict[entry[0]] = entry
y0dict[y[0]] = y
将x0dict
和y0dict
初始化为{}
后。然后,不是再次遍历两个完整的数据集,而是可以遍历其中一个词:
for x0, xrow in x0dict:
if x0 in y0dict:
yrow = y0dict[x0]
# Do the col{1,2,3,4}_diff stuff here
作为奖励,第二和第三个循环中的not in
的工作方式相同。
该行
(yrow[1] != xrow[1] or yrow[2] != xrow[2] or yrow[3] != xrow[3] or yrow[4] != xrow[4])
可以替换为更好看的
yrow[1:5] != xrow[1:5]
由于您的代码现在正在使用,i
从未使用过,但如果您需要该计数,则最终只会说i = len(AllData_2)
,因为它只会在循环中每次运行增加一次超过AllData_2
。
最后,您的foundit
变量目前没有用处。它仅用于在设置为0后立即使用foundit == 0
来控制流量,因此始终将其评估为True
并将其设置为无效。
答案 1 :(得分:1)
在顶部,您可以将其缩小很多。
y0list = []
for y in AllData_2:
y0list.append(y[0])
只是一种冗长的说法
y0list = [y[0] for y in AllData_2]
你可以在内置比较中使用。 以下
(yrow[1] != xrow[1] or yrow[2] != xrow[2] or yrow[3] != xrow[3] or yrow[4] != xrow[4])
可以表示为
yrow[1:] != xrow[1:]
更不容易发生复制/粘贴错误。
为了加快速度,您可以避免进行O(n ** 2)次比较。由于您只关心第一个列元素是否相同,因此您可以通过第一个元素将它们捆绑在一起。
index = {}
for yrow in AllData_2:
key = yrow[0]
list = index.get(key)
if list is None:
list = []
index[key] = list
list.append(yrow)
for xrow in AllData_1:
list = index.get(xrow[0])
if list is None: continue
for yrow in list:
# Do all your comparison here