我有两个堆栈溢出问题的列表,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#我的第一个想法是将变量标记转换为set变量,然后使用Pandas进行合并,因为set忽略位置。然而,Pandas似乎不允许set变量作为关键变量。所以我现在用for循环搜索B组,但是由于B组有1300万次观察,所以速度非常慢。
我的问题是: 1. Python中有没有其他方法可以通过一列集合进行合并,并且可以分辨重叠标记的数量? 2.如何提高for循环搜索的效率?
发布于 2017-07-11 02:08:30
这可以使用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#]让我们将两个数据帧中的右列平平。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 opacitydf2也是如此,它也是扁平的。
现在是魔法了。我们将在Tag列上执行一个Tag,然后在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 发布于 2017-07-11 02:12:10
就处理速度而言,应该是可以的。但是,如果标记数量太大,可能会出现内存问题。如果您只需要为一个Id找到相同标记的问题,我建议您编写一个简单的函数并调用df.apply。如果您需要检查大量If并找到带有相同标记的问题,我会说上面的方法会更好。
(打算把它作为评论,但没有足够的声誉.(叹息)
https://stackoverflow.com/questions/45024037
复制相似问题