首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Pandas按一列集合合并?

如何使用Pandas按一列集合合并?
EN

Stack Overflow用户
提问于 2017-07-11 01:40:05
回答 2查看 376关注 0票数 1

我有两个堆栈溢出问题的列表,A组和B组都有两个列,Id和Tag。例如:

代码语言:javascript
复制
|Id        |Tag
| -------- | --------------------------------------------
|2         |c#,winforms,type-conversion,decimal,opacity

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

代码语言:javascript
复制
|Id        |Tag
|----------|---------------------------
|3         |c#
|4         |winforms,type-conversion
|5         |winforms,c#

我的第一个想法是将变量标记转换为set变量,然后使用Pandas进行合并,因为set忽略位置。然而,Pandas似乎不允许set变量作为关键变量。所以我现在用for循环搜索B组,但是由于B组有1300万次观察,所以速度非常慢。

我的问题是: 1. Python中有没有其他方法可以通过一列集合进行合并,并且可以分辨重叠标记的数量? 2.如何提高for循环搜索的效率?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-11 02:08:30

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

这是我正在使用的设置:

代码语言:javascript
复制
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帮助了:

代码语言:javascript
复制
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列上执行一个Tag,然后在ID上执行groupby以查找重叠标记的计数。

代码语言:javascript
复制
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将分组列指定为索引,因此我们重新设置它。

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

代码语言:javascript
复制
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调用链接到第一个表达式:

代码语言:javascript
复制
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 
票数 3
EN

Stack Overflow用户

发布于 2017-07-11 02:12:10

  • 步骤1列出所有标签
  • 步骤2创建每个标记的二进制表示,即使用位1或0来表示是否有标记。
  • 步骤3要找到任何ID共享相同的标记,您可以调用一个简单的应用函数来解码二进制表示。

就处理速度而言,应该是可以的。但是,如果标记数量太大,可能会出现内存问题。如果您只需要为一个Id找到相同标记的问题,我建议您编写一个简单的函数并调用df.apply。如果您需要检查大量If并找到带有相同标记的问题,我会说上面的方法会更好。

(打算把它作为评论,但没有足够的声誉.(叹息)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45024037

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档