更快地编写以下代码

时间:2015-04-16 20:59:38

标签: python python-2.7 csv numpy pandas

我正在解析数据,并在将数据导入数据库之前将其写入csv文件。在解析期间,我会保留一份作者姓名列表(这些名称往往会重复出现)。我正在生成两个csv文件,其中一个我有两个列:作者的id(我通过计数器手动生成)和作者的名字。第二个csv文件,也有两列,author_id和publication_id。我发布可以有很多作者,作者可以有很多出版物。

现在这是我的问题。我写的代码花了很长时间来解析。我有超过200万条记录,而且它的速度大约是每小时6,000条记录。我认为最大的问题是,在我写作之前,我必须先搜索作者是否已经找到过。

我就是这样做的:

#authors_list is a list that has the authors of the current publication I'm parsing. 
#all_authors is a list that has all the authors found so far.

j=0 #keeps track of authors index in all_authors list
flag=0

for a in authors_list:
    #check to see if authors already exists
    allauthors = np.array(all_authors)
    if a in allauthors[:,1]:
         flag = 1
         k = 0 #k gives me current index of found author
         while flag and k<len(allauthors):
             if allauthors[k][1]==a:
                 index = k
                 flag = 0
             else:
                 k+=1
         print "Author exists: ", allauthors[k][1]
         aup.writerow([k,pid])
    else:
         all_authors.append([j,a]) 
         au.writerow([j,a])
         aup.writerow([j,pid]) 

我觉得必须有一种更快的方法来实现这项检查。也许用熊猫?或者以更好的方式numpy?我对两者都很陌生。

1 个答案:

答案 0 :(得分:4)

主要的问题是,每篇文章中的每位作者都会对您到目前为止的所有作者进行线性搜索。

仅此一项就具有O(N²)的复杂性 - 但更糟糕的是,您正在使用行allauthors = np.array(all_authors)重新创建每个作者姓名的数据结构,如果您获得“6000 /小时”(例如第一次小时更可能是6000 :-))

有时,简单就更好了。其他时候,更简单,更好,更好。 它仍然可以直接写入SQL,避免传递你在这里看到的CSV文件,但是你的问题中的上下文太少,无法编写这样的例子。

#authors_list is a list that has the authors of the current publication I'm parsing. 
#all_authors is a list that has all the authors found so far.

last_author_id = 0 #keeps track of authors index in all_authors list
all_authors = {}
for author in authors_list:
    if author in all_authors:
        author_index = all_authors[author]
        print "Author exists: ", author_index
    else:
        last_author_id += 1
        all_authors[author] = author_index = last_author_id
        au.writerow([author_index, author])
    aup.writerow([author_index, pid])

请注意主要变化:

  • 根本不使用Numpy。 Numpy具有强大的数字处理功能 - 线性文本搜索在使用numpy
  • 时没有任何改进
  • 不在每个作者姓名上重新创建数据结构
  • 使用Python字典(或集合)来存储作者名称而不是Numpy序列,从时间为O(N)的线性搜索更改为时间为O(1)的固定哈希搜索< / LI>

这也是一个可能的问题:我天真地保留所有作者并在dict中创建ID,在内存中。对于~GB RAM类服务器/桌面和200万个1行文本记录应该没问题 - 但是如果这些数字发生变化,那么直接写入SQL服务器就可以解决这个问题(任何DBMS都应该保持搜索的延迟较低(如果你有一个作者名称的索引,以及透明方式的正确缓存,用于这样的简单查询)