所以这是一个大问题:
我有一个各种出版物的作者和合著者的列表。此列表可能如下所示:
[[['A','uni'],[['B','uni'],['C','uni'],['D','uni'],['E','uni']]],
[['E','uni'],[['A','uni'],['F','uni'],['G','uni']]]]因此,作者A与作者B、C和D在一份出版物上合作,作者E与作者A、F和G在另一份出版物上合作。
我需要的是所有作者的列表,即使他们只是被列为合著者(B,C,D,F,G),以及他们与谁一起写了多少论文。因此,所有主要作者(A和E)都与他们的合著者(A与B,C,D,E;E与A,F,G)一起工作,但论文的合著者也一起工作(B与C,D,E以及A等)。最重要的是,我需要知道他们合作了多少篇论文。
所以这个小例子的最终结果是:
[[['A','uni'],[['B','uni',1],['C','uni',1],['D','uni',1],['E','uni',2],['F','uni',1],['G','uni',1]]],
[['B','uni'],[['A','uni',1],['C','uni',1],['D','uni',1],['E','uni',1]]],
[['C','uni'],[['A','uni',1],['B','uni',1],['D','uni',1],['E','uni',1]]],
[['D','uni'],[['A','uni',1],['B','uni',1],['C','uni',1],['E','uni',1]]],
[['E','uni'],[['A','uni',2],['B','uni',1],['C','uni',1],['D','uni',1],['F','uni',1],['G','uni',1]]],
[['F','uni'],[['A','uni',1],['E','uni',1],['G','uni',1]]],
[['G','uni'],[['A','uni',1],['E','uni',1],['F','uni',1]]]]好吧,老实说,这有点令人困惑,但我希望你能理解我的意思。( uni条目代表作者工作的大学。可能仍包括其他信息,但这与此任务无关)
我有这个初始列表,它是通过我编写的解析数据库的python脚本获得的。我想创建一个图表,显示我们与谁一起写的内容和频率。
我已经玩了一段时间了,就是找不到一个好的解决方案。我想我能够写出一些有用的东西,但它不会很好,效率也不会很高,而且非常耗时。那么,有没有一种快速、高效的方法来解决这个问题呢?我的例子现在只有两个出版物,但我必须分析大约10000个出版物,其中一些有几百个合著者……
发布于 2012-10-03 04:47:17
我的版本:
from collections import defaultdict
from collections import Counter
from itertools import chain
L = [[['A', 'uni'], [['B', 'uni'], ['C', 'uni'], ['D', 'uni'], ['E', 'uni']]], [['E', 'uni'], [['A', 'uni'], ['F', 'uni'], ['G', 'uni']]]]
d = defaultdict(Counter)
for publication in L:
authors = [tuple(a) for a in chain([publication[0]], publication[1])]
for author in authors:
d[author].update(authors)
for k, v in d.iteritems():
print k, [(author[0], author[1], counter)
for author, counter in v.iteritems() if author[0] != k[0]]输出:
('B', 'uni') [('A', 'uni', 1), ('D', 'uni', 1), ('E', 'uni', 1), ('C', 'uni', 1)]
('A', 'uni') [('B', 'uni', 1), ('F', 'uni', 1), ('D', 'uni', 1), ('G', 'uni', 1), ('E', 'uni', 2), ('C', 'uni', 1)]
('F', 'uni') [('A', 'uni', 1), ('G', 'uni', 1), ('E', 'uni', 1)]
('D', 'uni') [('A', 'uni', 1), ('B', 'uni', 1), ('E', 'uni', 1), ('C', 'uni', 1)]
('G', 'uni') [('A', 'uni', 1), ('E', 'uni', 1), ('F', 'uni', 1)]
('E', 'uni') [('B', 'uni', 1), ('A', 'uni', 2), ('F', 'uni', 1), ('D', 'uni', 1), ('G', 'uni', 1), ('C', 'uni', 1)]
('C', 'uni') [('A', 'uni', 1), ('D', 'uni', 1), ('B', 'uni', 1), ('E', 'uni', 1)]发布于 2012-10-03 04:40:02
from collections import defaultdict
L = [[['A','uni'],[['B','uni'],['C','uni'],['D','uni'],['E','uni']]],
[['E','uni'],[['A','uni'],['F','uni'],['G','uni']]]]
res = defaultdict(set)
for x, y in L:
x = [tuple(x)]
y = map(tuple, y)
row = x+y
for i in row:
print set(row)
res[i] |= set(row)
for k, v in res.items():
v.remove(k)
print k, list(v)输出:
('B', 'uni') [('A', 'uni'), ('D', 'uni'), ('E', 'uni'), ('C', 'uni')]
('A', 'uni') [('B', 'uni'), ('F', 'uni'), ('D', 'uni'), ('G', 'uni'), ('E', 'uni'), ('C', 'uni')]
('F', 'uni') [('A', 'uni'), ('G', 'uni'), ('E', 'uni')]
('D', 'uni') [('A', 'uni'), ('B', 'uni'), ('E', 'uni'), ('C', 'uni')]
('G', 'uni') [('A', 'uni'), ('E', 'uni'), ('F', 'uni')]
('E', 'uni') [('B', 'uni'), ('A', 'uni'), ('F', 'uni'), ('D', 'uni'), ('G', 'uni'), ('C', 'uni')]
('C', 'uni') [('A', 'uni'), ('D', 'uni'), ('B', 'uni'), ('E', 'uni')]发布于 2012-10-03 04:44:18
你不需要数据库,但你首先需要一些数据结构来保存和表示你所有的信息。我不会编写完整的类,只会编写它们的重要属性。
class Author(object):
name
university
class Publication(object):
name
date
class Authorship(object)
author
publication
main_author(bool)接下来,您必须组织这些对象。作者和出版物应该是独一无二的,所以如果你的数据集不超过几百MB,你可以把它们分别放在普通字典中。它们必须通过唯一的属性进行索引。如果author.name不足以满足这一要求,可以使用一个由大学和作者姓名组成的元组,或者更好的生日或与作者相关的内容(如果有),因为大学可能会发生变化。
对于作者身份,你应该创建不同的索引,这样你就可以更快地搜索,而不需要一直迭代整个列表。也许您想要一些defaultdict(list),由包含其出版物的作者索引,否则另一个defaultdict(list),与出版物一起索引。要注意保持一致性(重复,数据错误可能是很严重的)。
在此之后,您只需迭代数据集并填充结构即可。
https://stackoverflow.com/questions/12697345
复制相似问题