熊猫:基于重复索引值加速df.loc

phi*_*ilE 5 python performance dataframe pandas

我有pandas DataFrame

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'x': ['a', 'b', 'c'],
    'y': [1, 2, 2],
    'z': ['f', 's', 's']
}).set_index('x')
Run Code Online (Sandbox Code Playgroud)

从中我想根据x选择数组中index()的值选择行

selection = ['a', 'c', 'b', 'b', 'c', 'a']
Run Code Online (Sandbox Code Playgroud)

通过使用df.loc如下可以获得正确的输出

out = df.loc[selection]
Run Code Online (Sandbox Code Playgroud)

df.loc遇到的问题是在大型DataFrame(2-7百万行)上运行速度很慢.有没有办法加快这个操作?我已经研究过eval(),但它似乎不适用于这样的索引值的硬编码列表.我也考虑过使用pd.DataFrame.isin,但是错过了重复值(每个唯一元素只返回一行selection).

Ale*_*ley 5

您可以通过使用reindex代替来获得不错的加速loc

df.reindex(selection)
Run Code Online (Sandbox Code Playgroud)

时间(版本 0.17.0):

>>> selection2 = selection * 100 # a larger list of labels
>>> %timeit df.loc[selection2]
100 loops, best of 3: 2.54 ms per loop

>>> %timeit df.reindex(selection2)
1000 loops, best of 3: 833 µs per loop
Run Code Online (Sandbox Code Playgroud)

这两种方法采用不同的路径(因此速度不同)。

loc通过向下调用来构建新的 DataFrame, get_indexer_non_unique它必然比简单的get_indexer(用于唯一值)更复杂。

另一方面,inreindex中的艰巨工作似乎是由generated.pyx 中take_*函数完成的。为了构建新的 DataFrame,这些函数似乎更快。