Pandas - 获取出现在两个不同数据框中的特征值

数据挖掘 Python 熊猫
2022-02-19 05:20:05

我有一个结构如下的 Pandas DataFrame:

    user_id movie_id    rating
0   1       1193        5
1   2       1193        5
2   12      1193        4
3   15      1193        4
4   17      1193        5
5   18      1193        4
6   19      1193        5
7   24      1193        5
8   28      1193        3

每行对应于用户为电影rating执行的一个事件例如,第一行表示用户对电影的评分为user_idmovie_id111935

该数据来自MovieLens项目。

我的目标是找到所有满足这两个条件的用户:

  • 588评分为的电影5
  • 3578评分为的电影3

对于上述每个条件,我想出了两个过滤的 DataFrame 对象:

ratings_588_5 = data[(data.movie_id == 588) & (data.rating == 5]
ratings_3578_3 = data[(data.movie_id == 3578) & (data.rating == 3)]

分别导致:

>>> ratings_588_5
user_id movie_id    rating
438     588         5
758     588         5
913     588         5
1024    588         5
1214    588         5

>>> ratings_3578_3
user_id movie_id    rating
45      3578        3
321     3578        3
467     3578        3
758     3578        3
1024    3578        3
1381    3578        3

在 Pandas 中,如何计算出现在两个 DataFrame 中list的所有数据?user_id

在这个例子中,我想要得到的结果是:

[758, 1024]
3个回答

你可以使用numpy.intersect1d()方法:

In [277]: np.intersect1d(a.user_id, b.user_id).tolist()
Out[277]: [758, 1024]

pd.core.common.intersection()方法,但它似乎很慢(至少在我的笔记本aabbDataFrames [参见下面的设置...]):

In [307]: pd.core.common.intersection(a.user_id, b.user_id).tolist()
Out[307]: [1024, 758]

aaDF(50K 行)和bbDF(60K 行)时序:

In [294]: aa = pd.concat([a] * 10**4, ignore_index=True)

In [295]: bb = pd.concat([b] * 10**4, ignore_index=True)

In [296]: aa.shape
Out[296]: (50000, 3)

In [297]: bb.shape
Out[297]: (60000, 3)

In [298]: %timeit aa.ix[aa.user_id.isin(bb.user_id),'user_id'].tolist()
10 loops, best of 3: 41.8 ms per loop

In [299]: %timeit np.intersect1d(aa.user_id, bb.user_id).tolist()
100 loops, best of 3: 5.36 ms per loop

In [300]: %timeit pd.merge(aa, bb, on='user_id').user_id.tolist()
...
skipped
...
MemoryError:

In [308]: %timeit pd.core.common.intersection(aa.user_id, bb.user_id).tolist()
10 loops, best of 3: 52.8 ms per loop

PS原始答案

一种可能的方法是将用户 ID 转换为普通的旧Python 集并检查交集:

users_rating_588_5 = set(ratings_588_5['user_id'])
users_rating_3578_3 = set(ratings_3578_3['user_id'])
users_matching = users_rating_588_5.intersection(users_rating_3578_3)
print(users_matching) # {1024, 758}

我更喜欢更多类似数据库的操作,例如加入:

intersection = pd.merge(ratings_588_5, ratings_3578_3, on=['user_id'], how='inner') print intersection.user_id.tolist()

这将输出:

[758, 1024]