根据共享值将行排序为组

时间:2015-02-23 22:43:38

标签: python parsing csv pandas

我有一个包含大量行的CSV,来自用户提交的表单。每行包括一个用户电子邮件,以及一个字段,供他们列出其组中的其他用户电子邮件。到目前为止,我已经使用Python和pandas编写了一个简短的脚本,将CSV加载到数据帧中并清理条目。

我想按组对行进行排序,但遇到了一些概念问题。由于用户输入了该列表,因此列表不一定完整或拼写正确。处理这个问题的最佳方法是什么?我是一个全新的解析这样的数据而且总体来说缺乏经验。

这里有一些示例数据来说明我的意思:

email,group
user1@a.com, "['user4@b.com','user3@c.com']"
user2@a.com,
user3@c.com, "['user1@a.com']"
user4@b.com, "['user1@a.com','user3@b.com']"

所以这里user1,user3和user4在一个组中。问题是user3只列出了user1。

我的第一个想法是将提交用户的电子邮件附加到组列表中,然后对列表进行排序,然后按字母顺序对列进行排序。但是,这仅适用于每个人的小组条目都已完成的情况。

我不想手工挑选200个团体,但我已经迷失了如何继续下去。 这是我目前的伪代码计划:

data # dataframe containing imported CSV
sorted_groups # result dataframe with equivalent rows, but sorted into groups
sort(data) by len(data[group])
for each row in data:
    append row to sorted_groups
    search for rows where email == entry in groups
    append matching rows to sorted_groups
    remove matching rows from data
    remove initial row from data

这绝对会因拼写错误而失败,只有当团队中至少有一个人把一切都弄好的时候才有效。不过,这是我目前最好的。

感谢您花时间阅读本文。如果我能澄清任何事情,请告诉我,并指出我正确的方向!

1 个答案:

答案 0 :(得分:1)

我不确定您的数据是如何存储的,因此我假设您有一个数据行列表,并且每行包含表单中输入的所有电子邮件地址。如,

rows = [['user1@a.com','user4@b.com','user3@c.com'],
        ['user2@a.com'],
        ['user3@c.com', 'user1@a.com'],
        ['user4@b.com','user1@a.com','user3@b.com']]

我还假设每个用户都属于一个且只有一个组,每个用户都提交了表单,每个用户都没有拼错他们的电子邮件。

我们可以使用

获取一组有效的电子邮件地址
  valid = {row[0] for row in rows}

我们可以构建一个字典,将用户映射到组,合并组,并删除无效的电子邮件。

ugDict = {}

for row in rows:
  mergedGroup = set(row) & valid
  for user in row:
    if user in ugDict:
      mergedGroup |= ugDict[user]
  for user in mergedGroup:
    ugDict[user] = mergedGroup

这将导致从用户到组的映射,并将包括任何错误的电子邮件地址。您必须决定如何验证电子邮件 - 您可能只想忽略它们。

现在,要获取一个已排序的组列表,请创建一组所有组,并使用已排序的函数。

sortedGroups = sorted({frozenset(g) for g in ugDict.values()})

frozenset(g)使python的set对象可以清除(即可排序)。

结果?

sortedGroups = [frozenset({'user2@a.com'}),
                frozenset({'user1@a.com', 'user3@b.com', 'user4@b.com'})]