基于多个列在DataFrame中搜索值

时间:2019-10-04 14:32:22

标签: pandas dataframe

问题: 为多个列值约束提取特定列的值(在本例中为“评级”)。

从如下所示的DataFrame开始

我的数据如下:

    userID  movieID rating
0   196 242 3
1   186 302 3
2   22  377 1

现在,我要提取以下情况的评分:

userID == 196
movieID == 242

结果应为3。

  

我使用以下代码解决了该问题:但这并不是很有效。有谁有更好的方法?

df.loc[df['userID'] == 196].where(df['movieID'] == 242).dropna()['rating']
     

哪位给我ID为242,用户ID为196的电影的评级。

1 个答案:

答案 0 :(得分:2)

Index在熊猫中的查找速度非常快,因此最好在可能的情况下使用它。如果用户一次只能为每部电影评分,MultiIndex就是理想选择。

df = df.set_index(['userID', 'movieID'])
df.at[(196, 242), 'rating']
#3

一些时间。设置索引后,查找非常快。

%timeit df.at[(userID, movieID), 'rating']
#19.9 µs ± 405 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

df1 = df.reset_index()
%timeit df1.loc[df1['userID'].eq(196) & df1['movieID'].eq(242), 'rating']
#1.2 ms ± 6.98 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

设置MultiIndex确实需要时间,因此单个查询的成本可能很高。但是对于许多人来说,它将很快得到回报,尤其是使用更大的DataFrame时。这是一个计时示例,可以在设置索引后使用唯一的MulitIndex。

import perfplot
import pandas as pd
import numpy as np

perfplot.show(
    setup=lambda n: pd.DataFrame({'userID': range(n),
                                  'movieID': range(n),
                                  'rating': range(n)}).set_index(['userID', 'movieID']), 
    kernels=[
        lambda df: df.at[(4 ,4), 'rating'],
        lambda df: df.loc[(df.index.get_level_values('userID') == 4) 
                          & (df.index.get_level_values('movieID') == 4), 'rating']
    ],
    labels=["MultiIndex", "Boolean Slice"],
    n_range=[2 ** k for k in range(5, 25)],
    equality_check=np.allclose,  
    xlabel="len(df)"
)

enter image description here