Python 编写以下代码的更快方法

Python 编写以下代码的更快方法,python,python-2.7,csv,numpy,pandas,Python,Python 2.7,Csv,Numpy,Pandas,我正在解析数据,并在将数据导入数据库之前将其写入csv文件。在解析过程中,我保留了一个作者姓名列表(往往会重复很多次)。我正在生成两个csv文件,其中一个有两列:作者id(我通过计数器手动生成)和作者姓名。第二个csv文件也有两列,作者id和出版物id。我的出版物可能有许多作者,一个作者可能有许多出版物 现在是我的问题。我写的代码花了太长的时间来解析。我有超过200万条记录,每小时大约有6000条记录。我相信最大的问题是,我必须在写作者之前搜索是否已经找到了作者 我就是这样做的: #author

我正在解析数据,并在将数据导入数据库之前将其写入csv文件。在解析过程中,我保留了一个作者姓名列表(往往会重复很多次)。我正在生成两个csv文件,其中一个有两列:作者id(我通过计数器手动生成)和作者姓名。第二个csv文件也有两列,作者id和出版物id。我的出版物可能有许多作者,一个作者可能有许多出版物

现在是我的问题。我写的代码花了太长的时间来解析。我有超过200万条记录,每小时大约有6000条记录。我相信最大的问题是,我必须在写作者之前搜索是否已经找到了作者

我就是这样做的:

#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]) 
#authors_list是一个包含我正在分析的当前出版物的作者的列表。
#all_authors是一个列表,其中包含迄今为止找到的所有作者。
j=0#跟踪所有作者列表中的作者索引
标志=0
对于作者列表中的作者:
#检查作者是否已经存在
allauthors=np.array(所有作者)
如果a在所有作者中[:,1]:
标志=1
k=0#k给出了找到的作者的当前索引

而flag和k的主要问题是,对于每篇文章中的每一位作者,到目前为止,你对所有作者都进行了线性搜索

这本身就具有O(N²)复杂性——但更糟糕的是,您正在使用行
allauthors=np.array(所有作者)
为每个作者名重新创建数据结构,如果您获得的是“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或not),从时间为O(N)的线性搜索更改为时间为O(1)的固定哈希搜索

这里还有一个可能的问题:我天真地将所有作者和创建的ID都保存在一个dict中,保存在内存中。对于~GB RAM类服务器/桌面和200万条1行文本记录来说,这应该是可以的-但如果这些数字发生变化,将所有内容直接写入SQL server将解决这一问题(任何DBMS都应该将搜索延迟保持在较低水平)(如果您有一个作者姓名索引),并以透明的方式为这样的简单查询提供正确的缓存)

主要问题是,对于每篇文章中的每一位作者,您都在对迄今为止拥有的所有作者执行线性搜索

这本身就具有O(N²)复杂性——但更糟糕的是,您正在使用行
allauthors=np.array(所有作者)
为每个作者名重新创建数据结构,如果您获得的是“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或not),从时间为O(N)的线性搜索更改为时间为O(1)的固定哈希搜索

这里还有一个可能的问题:我天真地将所有作者和创建的ID都保存在一个dict中,保存在内存中。对于~GB RAM类服务器/桌面和200万条1行文本记录来说,这应该是可以的-但如果这些数字发生变化,将所有内容直接写入SQL server将解决这一问题(任何DBMS都应该将搜索延迟保持在较低水平)(如果您有作者姓名的索引),并且对于这样的简单查询,正确的缓存是透明的)

作为第一步,您可以加载第一个csv,然后删除重复的作者,并将其作为干净的csv写入,这听起来像是一个混乱的多对多关系,听起来像出版物是这里唯一的东西,因此您可能希望为每个作者重复出版物。您处理的是本质上的“外键”"而且记录数量惊人:它已经超过了您应该将其放入SQL数据库而不是CSV文件的程度。这并不难做到,即使是内置在Python中的sqlite也能很好地为您服务。@jsbueno我最初让它直接插入SQL数据库。但这需要更长的时间。后来有人告诉我它可能会很快呃,只需将其整齐地解析为csv文件,然后使用类似sqlite3上的.import命令将其直接导入到我的表中。这就是我在这里所做的。好吧-我找到了一些让它花费很长时间的原因-TL;DR:numpy不是您需要的。我将提供一个可能有用的答案。即使您无法实现/不喜欢我的答案,我也会建议您删除“numpy”从问题的标题来看,这不是适合这项工作的工具-你正在做文本数据处理。作为第一步,你可以加载第一个csv,然后删除重复的作者,并将其写为干净的csv,这听起来像是一个混乱的多对多关系,听起来像出版物是这里唯一的东西,所以你可以可能想为每个作者重复这些出版物,或者你是dea