基于多列在 DataFrame 中搜索值

aze*_*q6d 5 dataframe pandas

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

从如下所示的 DataFrame 开始

我的数据如下:

    userID  movieID rating
0   196 242 3
1   186 302 3
2   22  377 1
Run Code Online (Sandbox Code Playgroud)

现在,我想提取以下案例的评级:

userID == 196
movieID == 242
Run Code Online (Sandbox Code Playgroud)

结果应该是 3。

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

df.loc[df['userID'] == 196].where(df['movieID'] == 242).dropna()['rating']
Run Code Online (Sandbox Code Playgroud)

这给了我 ID 为 242、用户 ID 为 196 的电影的评级。

ALo*_*llz 8

Indexpandas 中的查找速度非常快,因此最好尽可能使用它。如果用户只能对每部电影评分一次,那么这MultiIndex是理想的选择。

\n\n
df = df.set_index([\'userID\', \'movieID\'])\ndf.at[(196, 242), \'rating\']\n#3\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

一些时间安排。一旦设置了索引,查找速度就非常快。

\n\n
%timeit df.at[(userID, movieID), \'rating\']\n#19.9 \xc2\xb5s \xc2\xb1 405 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 100000 loops each)\n\ndf1 = df.reset_index()\n%timeit df1.loc[df1[\'userID\'].eq(196) & df1[\'movieID\'].eq(242), \'rating\']\n#1.2 ms \xc2\xb1 6.98 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

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

在此输入图像描述

\n