我正在使用二部图分析我下载的关于给定主题和地理位置的推文的网络和语义值。
使用Python,我创建了一个.net文件,其中包含2组节点和边。这个文件是我单独创建的文件的合并:2组顶点和边缘。问题是创建。net文件的edge组件。
我有三个文件:
- tweeterers.csv包含发送者/tweeterers ("number/ID"one_answers"name")
- words.csv,包含我从tweets中提取的语义标签/单词。格式为"编号/ID"+"名称","编号"从上述文件的最后一个"编号"开始。每行有0到6个字
- Names_Text_full_clean.csv,包含tweeterers和words。每行包含1个推特者的名字和0到6个单词。这个文件将为我提供推特者和单词之间的关联,用于图表。
我基本上看每一条推文,看一个字,看是否有关联。如果是,我写下关联(这是一条边)。这是三圈。对于中等规模的网络来说,这是非常慢的:一个有~650个节点和~18000个边的网络在Mac Mini 2.7GHz四核上花了我将近2天的时间。
任何帮助加快它将非常感激!
代码如下:
import csv # csv library is to handle csv files
# open the twetterers file and make it available in 'reader1'
file_read1 = open('tweeterers.csv', 'rU')
reader1 = csv.reader(file_read1)
# open the file for writing and make it available in 'writer'
file_write=open('edges.csv', 'wb')
writer=csv.writer(file_write)
for sender in reader1:
file_read2 = open('words.csv', 'rU')
reader2 = csv.reader(file_read2)
for word in reader2:
file_read = open('Names_Text_full_clean.csv', 'rU')
reader = csv.reader(file_read)
for match in reader:
for elem in range (1,len(match)):
if sender[1] == match [0]:
if word [1] == match [elem]:
a = sender[0],word[0]
writer.writerow(a)
print "I wrote a record: it's: ",a
file_read.close()
file_read1.close()
file_read2.close()
file_write.close()
使用字典。例如,第一步是只读取Names_Text_full_clean.csv
一次,并将结果存储在字典中,以match[0]
为索引。因为可能有好几次相同的match[0]
,您需要将可能的多个match
对象的列表存储为一个值。
import collections
by_sender = collections.defaultdict(list)
file_read = open('Names_Text_full_clean.csv', 'rU')
reader = csv.reader(file_read)
for match in reader:
by_sender[match[0]].append(match)
然后在嵌套循环中,你可以替换
for match in reader:
if sender[1] == match [0]:
和下面的循环,它可能要小上百倍:
for match in by_sender[sender[1]]:
进一步的优化是不将match
存储在列表by_sender[match[0]]
中,而是存储set(match[1:])
。实际上,您只需要查看特定条目(在本例中为word[1]
)是否等于match[1:]
中的任何一项。而不是循环计算,它可以通过word[1] in my_set
来完成。
这可能已经足够了,但是"最终目标"是只读取所有三个文件一次。您可以将其中两个文件的内容存储在一些合适的字典中,并且仅在遍历第三个文件时才进行字典查找(或"设置查找",这也非常快)。