用python进行作者关系分析

用python进行作者关系分析,python,relationship,Python,Relationship,所以这是一个大问题: 我有一份各种出版物的作者和合著者名单。 此列表可能如下所示: [[['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','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脚本得到的。我想创建一个图表,显示wo与谁以及多久写一次

我已经玩了一段时间了,我就是找不到一个好的解决办法。我想我可以写一些有用的东西,但它不会很好,也不会很高效,也不会很耗时。 那么,有没有一种快速的、类似蟒蛇的方法来解决这个问题呢?我的例子现在只有两个出版物,但我必须分析大约10000个出版物,其中一些有几百个合著者

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')]

您不需要数据库,但首先需要一些数据结构来保存和表示所有信息。我不会写完整的类,只写它们的重要属性

class Author(object):
    name
    university        

class Publication(object):
    name
    date

class Authorship(object)
    author
    publication
    main_author(bool)
接下来,您必须组织这些对象。作者和出版物应该是独一无二的,所以如果您的数据集不超过几百MB,您可以将它们分别放在普通词典中。它们必须由唯一属性索引。如果author.name不足以满足这一要求,那么可以使用university和author name的元组,或者更好的生日或与作者相关的内容(如果可用),因为大学可以更改

对于作者身份,您应该创建不同的索引,这样您可以更快地搜索,而无需一直迭代整个列表。也许您需要一些由包含其出版物的作者编制索引的defaultdict(列表),或者另一个使用出版物编制索引的defaultdict(列表)。注意保持一致性(重复,数据错误可能很残酷)

之后,您只需迭代数据集并填充结构即可。

我的版本:

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)]

我知道这没有帮助,但是否应该在数据库中定义作者之间的关系?我不知道,如果有,我也无权访问它。我通过解析每个出版物的xmlmarc来获取信息,这样我只得到出版物的主要作者和合著者。因此,我的初始列表也可能,甚至很可能有两次或两次以上是同一位主要作者,并且有不同/相同的合著者。正如你所见,这并不容易。你在这里谈论的是多少出版物?100美元?1000秒?1000秒。一开始我会分析大约10000个,但可能会上升到500000个。现在可以投票了!每个答案都很有帮助,但@kalgasnik的答案是我一直在寻找的解决方案!非常感谢大家!不错,但如果我能正确解释的话,这并不能说明一些人在一起工作的频率。哇,我花了大约1周120英里才走到这一步。美好的但是,是否也有一种方法可以计算作者一起发表了多少出版物?A和E有两份出版物,但A和B只有一份。对不起,我不能投票,因为我没有足够的声誉…啊,好吧,我完全错过了计数的要求:)正如@kalgasnik所显示的那样-这并不是更难对付的计数器,而是@gnibbler的答案给你同样的结果!正是我需要的!我总是再一次让我惊讶,你能做的事情多么简单,而我尝试解决的问题又多么复杂!非常感谢你!非常感谢。我理解你回答的想法,但不具备实施的技能。而且我还没有时间来发展这些技能,但一旦我这样做了,我会重新阅读你的答案并从那里开始!这是一个很好的指向正确方向的指针,但现在我将使用@kalgasnik的答案,因为它只是一个小型的uni项目。但是非常感谢!