Создать список ребер из словаря Python - PullRequest
1 голос
/ 27 декабря 2011

У меня есть словарь словарей со следующей структурой:

1:{'Amendment': '1', 
   'status': 'Stadf\xc3\xa6stet', 
   'Name': 'Bodil Kornbek', 
   'title': 'L 1 Forslag til till\xc3\xa6gsbevillingslov for 2004.', 
   'fremsat': '2005-03-04', 
   'Vote.Numeric': '2', 
   'PSession': '1', 
   'vedtaget': '2005-04-12', 
   'Lsession': '3', 
   'Voteid': '38', 
   'Month': '4', 
   'Year': '2005', 
   'Vote': 'Frav\xc3\xa6rende', 
   'Party': 'KD', 
   'Law': 'L 1', 
   'ministerie': 'Finansministeriet'}

диапазон ключей от 1 до ок. 500000, и каждый вложенный словарь содержит информацию об одном члене датского парламента за один голос. Кроме того, есть информация, которая идентифицирует уникальный голос, за который проголосовал участник. Я хотел бы, чтобы каждый участник извлек все голоса, в которых этот участник был активен, и сравнивал бы поведение участников, участвующих в голосовании, со всеми остальными участниками, которые были активны в том же подгруппе голосов, итеративно.

В идеале для каждого участника я бы сравнил этого члена с одним другим участником по голосам, в которых они были активны, и вычислил долю голосов, в которых они проголосовали, одинаково для всех их общих голосов. Если доля больше, чем, скажем, 0,65, то пара добавляется в список.

Таким образом, конечными результатами должен быть список в формате:

[member1, member2
 member1, member4
 member1, member7
 member2, member5
 etc..
] 

Может кто-нибудь показать мне, как это можно сделать в python?

1 Ответ

4 голосов
/ 27 декабря 2011

Во-первых, давайте преобразуем данные (я сделаю некоторые предположения здесь) так, чтобы ключи словаря были членами парламента (обозначены Name), а данные для каждого - отображение того, как они проголосовали ( Vote.Numeric) по каждой проблеме (Voteid), поэтому Voteid s являются ключами в этом под-словаре. Мы можем отказаться от остальной информации как не относящейся к делу.

Необычный процессуальный путь:

member_to_votes = defaultdict(dict)
for item in vote_data:
    member_to_votes[item['Name']][item['Voteid']] = item['Vote.Numeric']

Теперь давайте определим сходство между двумя записями голосования:

def votes_agree(member_a, member_b, threshold):
    # Find the union of issues they voted on...
    issues = set(member_a.keys()).union(member_b.keys())
    # See how many of these they voted the same way on (we use a placeholder
    # if one member did not vote on the issue, so that they automatically
    # disagree) and compare the fraction of agreeing votes to the threshold.
    # There is a little hack in here: `True` is 1 in a numeric context, and
    # `False` is zero, so we can add up the boolean results directly.
    return sum(
        member_a.get(issue, None) == member_b.get(issue, None)
        for issue in issues
    ) / float(len(issues)) >= threshold

Теперь мы можем создать все пары членов и посмотреть, какие из них согласны:

def agreeing_members(member_to_votes, threshold):
    return [
        [a, b] for a, b in itertools.combinations(member_to_votes.keys(), 2)
        if votes_agree(member_to_votes[a], member_to_votes[b], threshold)
    ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...