我正在尝试使用基本python在一个有170万行和4个变量的表格上进行非等号自连接。数据如下所示:
product position_min position_max count_pos
A.16 167804 167870 20
A.18 167804 167838 15
A.15 167896 167768 18
A.20 238359 238361 33
A.35 167835 167837 8
这是我使用的代码:
import csv
from collections import defaultdict
import sys
import os
list_csv=[]
l=[]
with open(r'product.csv', 'r') as file1:
my_reader1 = csv.reader(file1, delimiter=';')
for row in my_reader1:
list_csv.append(row)
with open(r'product.csv', 'r') as file2:
my_reader2 = csv.reader(file2, delimiter=';')
with open('product_p.csv', "w") as csvfile_write:
ecriture = csv.writer(csvfile_write, delimiter=';',
quotechar='"', quoting=csv.QUOTE_ALL)
for row in my_reader2:
res = defaultdict(list)
for k in range(len(list_csv)):
comp= list_csv[k]
try:
if int(row[1]) >= int(comp[1]) and int(row[2]) <= int(comp[2]) and row[0] != comp[0]:
res[row[0]].append([comp[0],comp[3]])
except:
pass
if bool(res):
for key, value in res.items():
sublists = defaultdict(list)
for sublist in value:
l=[]
sublists[sublist[0]].append(int(sublist[1]))
l.append(str(key) + ";"+ str(min(sublists.keys(), key=(lambda k: sublists[k]))))
ecriture.writerow(l)
我应该在“product_p.csv”文件中得到这个:
'A.18'; 'A.16'
'A.15'; 'A.18'
'A.35'; 'A.18'
代码的作用是两次读取同一个文件,第一次完全读取并将其转换为列表,第二次逐行读取,并根据 position_min 和 position_max 的条件找到每个产品(第一个变量)所属的所有产品,然后通过保留 count_pos 最小的产品来选择其中之一。
我在原始数据的样本上尝试了这个代码,它可以工作,但是在170万行的情况下,运行数小时仍然没有结果。有没有一种方法可以在没有或者少循环的情况下进行操作?是否有人可以帮助使用基本的Python库进行优化?
提前感谢您。
A16 A35
,但你实际上得到的是A35 A16
,这样可以吗? - imxitizpandas
来完成,但是pandas
的速度比你的代码慢。我已经测试了2000个数据集,但是你的代码比我的快。如果我确切地理解了你要做什么,我可能会尝试其他方法!我注意到你的代码中,你不必为完全相同的数据读取文件两次,你可以在第二次使用之前的数据。我没有检查这是否使你的代码更快,但我注意到了这一点。 - imxitiz