Dav*_*ard 43 python dataframe intersect pandas
假设我有这样的格式(叫他们两个dataframes df1和df2):
+------------------------+------------------------+--------+
| user_id | business_id | rating |
+------------------------+------------------------+--------+
| rLtl8ZkDX5vH5nAx9C3q5Q | eIxSLxzIlfExI6vgAbn2JA | 4 |
| C6IOtaaYdLIT5fWd7ZYIuA | eIxSLxzIlfExI6vgAbn2JA | 5 |
| mlBC3pN9GXlUUfQi1qBBZA | KoIRdcIfh3XWxiCeV1BDmA | 3 |
+------------------------+------------------------+--------+
Run Code Online (Sandbox Code Playgroud)
我希望得到的是有一个共同的所有行的数据帧user_id中df1和df2.(即,如果user_id是在两个df1和df2,在输出中包括数据帧的两行)
我可以想出很多方法来解决这个问题,但它们都让我感到笨拙.例如,我们可以user_id在每个数据帧中找到所有唯一的s,创建一组,找到它们的交集,用结果集过滤两个数据帧并连接两个过滤的数据帧.
也许这是最好的方法,但我知道熊猫很聪明.有更简单的方法吗?我看过了,merge但我认为这不是我需要的.
小智 62
我的理解是这个问题在这篇文章中得到了更好的回答.
但简而言之,使用此方法对OP的答案很简单:
s1 = pd.merge(df1, df2, how='inner', on=['user_id'])
Run Code Online (Sandbox Code Playgroud)
这给了s1 5列:user_id和df1和df2中的每两列.
Phi*_*oud 11
如果我理解正确的话,你可以使用的组合Series.isin()和DataFrame.append():
In [80]: df1
Out[80]:
rating user_id
0 2 0x21abL
1 1 0x21abL
2 1 0xdafL
3 0 0x21abL
4 4 0x1d14L
5 2 0x21abL
6 1 0x21abL
7 0 0xdafL
8 4 0x1d14L
9 1 0x21abL
In [81]: df2
Out[81]:
rating user_id
0 2 0x1d14L
1 1 0xdbdcad7
2 1 0x21abL
3 3 0x21abL
4 3 0x21abL
5 1 0x5734a81e2
6 2 0x1d14L
7 0 0xdafL
8 0 0x1d14L
9 4 0x5734a81e2
In [82]: ind = df2.user_id.isin(df1.user_id) & df1.user_id.isin(df2.user_id)
In [83]: ind
Out[83]:
0 True
1 False
2 True
3 True
4 True
5 False
6 True
7 True
8 True
9 False
Name: user_id, dtype: bool
In [84]: df1[ind].append(df2[ind])
Out[84]:
rating user_id
0 2 0x21abL
2 1 0xdafL
3 0 0x21abL
4 4 0x1d14L
6 1 0x21abL
7 0 0xdafL
8 4 0x1d14L
0 2 0x1d14L
2 1 0x21abL
3 3 0x21abL
4 3 0x21abL
6 2 0x1d14L
7 0 0xdafL
8 0 0x1d14L
Run Code Online (Sandbox Code Playgroud)
这基本上是您使用惯用pandas方法描述为"笨重"的算法.请注意重复的行索引.另外,请注意,如果df1并且df2没有重叠的行索引,这将不会为您提供预期的输出,即if
In [93]: df1.index & df2.index
Out[93]: Int64Index([], dtype='int64')
Run Code Online (Sandbox Code Playgroud)
实际上,如果它们的行索引不相等,它将不会给出预期的输出.
在SQL中,这个问题可以通过以下几种方法来解决:
select * from df1 where exists (select * from df2 where df2.user_id = df1.user_id)
union all
select * from df2 where exists (select * from df1 where df1.user_id = df2.user_id)
Run Code Online (Sandbox Code Playgroud)
或加入然后取消透视(可能在 SQL Server 中)
select
df1.user_id,
c.rating
from df1
inner join df2 on df2.user_i = df1.user_id
outer apply (
select df1.rating union all
select df2.rating
) as c
Run Code Online (Sandbox Code Playgroud)
第二个可以用 pandas 编写,如下所示:
>>> df1 = pd.DataFrame({"user_id":[1,2,3], "rating":[10, 15, 20]})
>>> df2 = pd.DataFrame({"user_id":[3,4,5], "rating":[30, 35, 40]})
>>>
>>> df4 = df[['user_id', 'rating_1']].rename(columns={'rating_1':'rating'})
>>> df = pd.merge(df1, df2, on='user_id', suffixes=['_1', '_2'])
>>> df3 = df[['user_id', 'rating_1']].rename(columns={'rating_1':'rating'})
>>> df4 = df[['user_id', 'rating_2']].rename(columns={'rating_2':'rating'})
>>> pd.concat([df3, df4], axis=0)
user_id rating
0 3 20
0 3 30
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
68302 次 |
| 最近记录: |