Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Python按集合列合并?_Python_Pandas_Dataframe_Merge_Set - Fatal编程技术网

如何使用Python按集合列合并?

如何使用Python按集合列合并?,python,pandas,dataframe,merge,set,Python,Pandas,Dataframe,Merge,Set,我有两个堆栈溢出问题列表,A组和B组。它们都有两列,Id和Tag。e、 g: |Id |Tag | -------- | -------------------------------------------- |2 |c#,winforms,type-conversion,decimal,opacity 对于A组中的每个问题,我需要在B组中找到所有匹配的问题,这些问题至少有一个重叠的标签——A组中的问题,与标签的位置无关。例如,这些问题都应该是匹配的问题: |I

我有两个堆栈溢出问题列表,A组和B组。它们都有两列,Id和Tag。e、 g:

|Id        |Tag
| -------- | --------------------------------------------
|2         |c#,winforms,type-conversion,decimal,opacity
对于A组中的每个问题,我需要在B组中找到所有匹配的问题,这些问题至少有一个重叠的标签——A组中的问题,与标签的位置无关。例如,这些问题都应该是匹配的问题:

|Id        |Tag
|----------|---------------------------
|3         |c#
|4         |winforms,type-conversion
|5         |winforms,c#
我的第一个想法是将变量标记转换成一个set变量,并使用Pandas合并,因为set忽略位置。然而,Pandas似乎不允许set变量作为关键变量。所以我现在使用for循环来搜索B组,但是速度非常慢,因为我在B组有1300万次观察

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

这可以通过使用
df.join
df.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#]
让我们将两个数据帧中的右列展平。帮助:

类似地,df2也是扁平的

现在是魔术。我们将在
Tag
列上执行
join
,然后在joined
ID
s上执行
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-重叠,请链a
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 
  • 第1步列出所有标签
  • 步骤2:创建每个标签的二进制表示,即使用位1或0表示是否有标签
  • 步骤3:要查找共享同一标记的任何ID,可以调用一个简单的apply函数来解码二进制表示
就处理速度而言,应该没问题。然而,如果标签的数量太大,可能会出现内存问题。如果您只需要为一个Id查找具有相同标记的问题,我建议您编写一个简单的函数并调用df.apply。如果您需要检查大量ID并找到具有相同标签的问题,我会说上述方法会更好


(本打算留下评论,但声誉不够……唉)

你是如何得到1300万个堆栈溢出问题的?API永远不会让你这么快完成。我是从Stack Exchange data dumps@COLDSPEEDOkay下载的。下一个问题。标签是由逗号分隔的标签组成的字符串类型还是标签列表?标签是由括号分隔的标签组成的字符串。但我可以使用正则表达式将其转换为标记列表。我现在正在读你的答案,看起来很有希望。非常感谢你!至少有一万个标签。如果我使用二进制表示,我将有数千列来表示问题的标记。如果超过一万个标签,我认为你不应该使用我上面提出的方法。我认为Coldspeed使用的方法会更好。有没有办法也显示重叠的标签?@Coldspeed抱歉,我以前忘了提到。我可以在连接时限制重叠标记的数量吗?因为有太多带有一个或两个重叠标记的问题,这会使输出表太长。所以我想把问题限制在只有3个或更多重叠标签的问题上。谢谢@小萌用
.query
,我在我的帖子中编辑。从现在开始,请不要在评论中重复要求和细节。它妨碍了未来读者的可读性。请一次查询一个问题。如果这解决了您的问题,请将其标记为已接受并提出新问题。我将不再回答注释中的任何问题。@COLDSPEED我在展平df2时遇到问题,它给出错误“根据规则“安全”将数组数据从dtype('float64')转换为dtype('int64')”。在从csv文件导入df2时,我已尝试使用dtype=int64。但我还是犯了同样的错误。但是,使用函数展平df1没有问题。df1和df2之间的唯一区别是df2比df1有更多的观测值。而df2.Id列的int可能更长。@Xiaomeng肯定会问一个新问题。我想我不知道如何解决内存错误!
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