python - 如何使用 Python Pandas 按列合并集合?

标签 python pandas dataframe merge set

我有 2 个 Stack Overflow 问题列表,A 组和 B 组。两者都有两列:Id 和 Tag。例如:

|Id        |Tag
| -------- | --------------------------------------------
|2         |c#,winforms,type-conversion,decimal,opacity

对于 A 组中的每个问题,我需要在 B 组中找到所有与 A 组中的问题至少有一个重叠标签的匹配问题,而与标签的位置无关。例如,这些问题都应该是匹配问题:

|Id        |Tag
|----------|---------------------------
|3         |c#
|4         |winforms,type-conversion
|5         |winforms,c#

我的第一个想法是将变量 Tag 转换为集合变量并使用 Pandas 进行合并,因为集合会忽略位置。然而,Pandas 似乎不允许设置变量作为关键变量。所以我现在使用 for 循环来搜索 B 组。但是它非常慢,因为我在 B 组中有 1300 万个观察值。

我的问题是: 1.Python中有没有其他方法可以按集合的列进行合并并可以知道重叠标签的数量? 2、如何提高for循环查找的效率?

最佳答案

这可以使用df.joindf.groupby来实现。

这是我正在使用的设置:

df1 = pd.DataFrame({ 'Id' : [2], 'Tag' : [['c#', 'winforms', 'type-conversion', 'decimal', 'opacity']]}) 

   Id                                                Tag
0   2  [c#, winforms, type-conversion, decimal, opacity]

df2 = pd.DataFrame({ 'Id' : [3, 4, 5], 'Tag' : [['c#'], ['winforms', 'type-conversion'], ['winforms', 'c#']]})  

   Id                          Tag
0   3                         [c#]
1   4  [winforms, type-conversion]
2   5               [winforms, c#]

让我们展平两个数据框中的右列。 This帮助:

In [2331]: from itertools import chain

In [2332]: def flatten(df):
      ...:     return pd.DataFrame({"Id": np.repeat(df.Id.values, df.Tag.str.len()),
      ...:                          "Tag": list(chain.from_iterable(df.Tag))})
      ...: 

In [2333]: df1 = flatten(df1)

In [2334]: df2 = flatten(df2)

In [2335]: df1.head()
Out[2335]: 
   Id              Tag
0   2               c#
1   2         winforms
2   2  type-conversion
3   2          decimal
4   2          opacity

对于 df2 也是如此,它也是扁平化的。

现在就是魔法了。我们将在 Tag 列上执行 join,然后在连接的 ID 上执行 groupby 以查找重叠计数标签。

In [2337]: df1.merge(df2, on='Tag').groupby(['Id_x', 'Id_y']).count().reset_index()
Out[2337]: 
   Id_x  Id_y  Tag
0     2     3    1
1     2     4    2
2     2     5    2

输出显示每对标签以及重叠标签的数量。没有重叠的对将被 groupby 过滤掉。

df.count 对重叠标签进行计数,df.reset_index 只是美化输出,因为 groupby 将分组列指定为索引,所以我们重置它。

要查看匹配的标签,您需要稍微修改上面的内容:

In [2359]: df1.merge(df2, on='Tag').groupby(['Id_x', 'Id_y'])['Tag'].apply(list).reset_index()
Out[2359]: 
   Id_x  Id_y                          Tag
0     2     3                         [c#]
1     2     4  [winforms, type-conversion]
2     2     5               [c#, winforms]

要过滤掉 1-重叠,请将 df.query 调用链接到第一个表达式:

In [2367]: df1.merge(df2, on='Tag').groupby(['Id_x', 'Id_y']).count().reset_index().query('Tag > 1')
Out[2367]: 
   Id_x  Id_y  Tag
1     2     4    2
2     2     5    2 

关于python - 如何使用 Python Pandas 按列合并集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45024037/

相关文章:

python - Keras 模型评估()与预测类()给出不同的精度结果

java - 从 Python 中使用 jar 运行 Java 程序

python - Groupby 聚合方法总是返回 NaN

r - data.frame 中列顺序的约束随机化

python - 如何从 Dataframe 列形成元组列表

python - 如何解压深层嵌套的可迭代结构

python - cx_freeze 不适用于 __init__ == __main__

python - Pandas groupby 重叠列表

python - 添加到 pandas python df 中的列

r - 如何使用 R 从列的每个单元格中删除重复的逗号分隔字符值