根据共享值对行进行分组
Sorting rows into groups based on shared values
我有一个包含大量行的 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
这肯定会因拼写错误而失败,并且只有在组中至少有一个人正确无误的情况下才会起作用。不过,这是我目前拥有的最好的。
感谢您抽出宝贵时间阅读本文。如果我能澄清任何问题,请告诉我,并指出正确的方向!
我不确定您的数据是如何存储的,所以我写这篇文章时假设您有一个数据行列表,并且每一行都包含在表单中输入的所有电子邮件地址。例如,
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 的集合对象可散列(即可排序)。
结果?
sortedGroups = [frozenset({'user2@a.com'}),
frozenset({'user1@a.com', 'user3@b.com', 'user4@b.com'})]
我有一个包含大量行的 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
这肯定会因拼写错误而失败,并且只有在组中至少有一个人正确无误的情况下才会起作用。不过,这是我目前拥有的最好的。
感谢您抽出宝贵时间阅读本文。如果我能澄清任何问题,请告诉我,并指出正确的方向!
我不确定您的数据是如何存储的,所以我写这篇文章时假设您有一个数据行列表,并且每一行都包含在表单中输入的所有电子邮件地址。例如,
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 的集合对象可散列(即可排序)。
结果?
sortedGroups = [frozenset({'user2@a.com'}),
frozenset({'user1@a.com', 'user3@b.com', 'user4@b.com'})]