我有两个csv文件。我试图删除某些列匹配的所有行。我以为我在Python中使用列表来做到这一点。我认为它很快,但它的运行方式太慢了。
我只想比较前3列,因为最后2列是不可靠的。但是,我想导出最后两列。
示例:
A = [
(Jack, Smith, New York, USA, 100),
(Jim, Doe, Cleveland, UK, 200),
(Frank, Johnson, Chicago, USA, 300)
]
B = [
(Jack, Smith, New York, United States, blank),
(Jerry, Smith, Cleveland, USA, blank),
(Frank, Johnson, Chicago, America, blank)
]
Matched List = [
(Jack, Smith, New York, USA, 100)
(Frank, Johnson, Chicago, USA, 300)
]
Desired List = [
(Jim, Doe, Cleveland, UK, 200)
]
所以我编写了两个嵌套的For Loops来比较两个列表并删除匹配的项目。但是,我的列表A是~50,000,列表B是600,000行。这需要3.5个小时。我需要在一组300,000和4,000,000行上运行它;但看到这需要多长时间,它会运行数天。
这里是两个For循环(我比较第0,7,9和10列。)
for Acquisition_row in Acquisition_list[:]:
for Leads_row in Leads_list:
if (Acquisition_row[0] == Leads_row[0]) and (Acquisition_row[7] == Leads_row[7]) and (Acquisition_row[9] == Leads_row[9]) and (Acquisition_row[10] == Leads_row[10]):
try:
Acquisition_list.remove(Acquisition_row)
Leads_list.append(Acquisition_row)
except:
print("Error!")
有没有办法加快速度?有更好的方法吗?我应该使用不同的编程语言吗?也许将它们上传到SQL db中的临时表并使用SQL?
谢谢!
答案 0 :(得分:2)
@kindall建议set()
或dict
跟踪您目前所看到的内容是正确的。
def getKey(row):
return (row[0], row[7], row[9], row[10])
# create a set of all the keys you care about
lead_keys = {getKey(r) for r in Leads_rows}
# save this off due to reverse indexing gyration
len_ac_list = len(Acquisition_list)
for i, ac_row in enumerate(Acquisition_list[::-1]):
ac_key = getKey(ac_row)
if ac_key in lead_keys: ## this look up is O(1)
index = len_ac_list - i - 1
Acquisition_list.pop(index)
Leads_list.append(ac_row)
## maybe: lead_keys.add(ac_key)
好处是:在创建一组密钥时,您只会迭代Leads_list一次(我为此选择了Leads_list,因为它是更大的列表,因此可以节省更多时间);并且你对Acquisition_list的查询需要恒定的时间,O(1)而不是O(n),其中n是len(Leads_list)。
在您的原始设置中,您最糟糕的是(n * m)或(300000 * 4000000)操作,这是......吨。使用set
s,您将只执行(n + m)或(30000 + 4000000)...比减少300,000倍。这就是1.2万亿件物品与.000004万亿件物品(400万件)之间的差异。