Pandas:从数据框中选择时速度很慢

noa*_*amk 5 python pandas

我有一个从字典列表创建的 DataFrame,它是从数据库中获取的。我正在尝试将其用作内存数据库,我使用以下函数进行查询:

def filter_entities(df, name1, name2):
    key = ((df.name1 == name1) &
           (df.name2 == name2))

    rows = df.loc[key]
    if len(rows) == 0:
        return None
    return rows.iloc[0]
Run Code Online (Sandbox Code Playgroud)

这样做似乎比我预期的要慢得多。即使对几百行进行测试,每次调用也需要大约 1 毫秒。我在创建数据框时尝试在这些列上设置索引,但它没有影响性能:

entities.set_index(['name1', 'name2'], drop=False, inplace=True)
Run Code Online (Sandbox Code Playgroud)

这是创建用于测试的数据集的快速方法:

import random, string
import pandas as pd
df = pd.DataFrame([{
   'name1': ''.join([random.choice(string.letters) for i in range(10)]),
   'name2': ''.join([random.choice(string.letters) for i in range(10)]),
   'val1': random.randint(0, 2**16),
   'val2': random.randint(0, 2**16),
   'val3': random.randint(0, 2**16),
   } for j in range(1000)])

In[27]: %timeit filter_entities(df, df['name1'][100], df['name2'][100])
1000 loops, best of 3: 1.91 ms per loop
Run Code Online (Sandbox Code Playgroud)

我正在尝试找到一种有效的方法来查询我的数据。有没有更好的方法在熊猫中做到这一点?

jor*_*ris 3

将列设置为索引确实提高了我的性能。

\n\n

与你原来的filter_entities功能:

\n\n
In [25]: %timeit filter_entities(df, df['name1'][100], df['name2'][100])\n\n1000 loops, best of 3: 1.36 ms per loop\n
Run Code Online (Sandbox Code Playgroud)\n\n

将列设置为索引后,然后对该帧建立索引:

\n\n
In [26]: df2 = df.set_index(['name1', 'name2'])\n\nIn [27]: %timeit df2.loc[df['name1'][100], df['name2'][100]]\n10000 loops, best of 3: 160 \xc2\xb5s per loop\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

请注意,函数中花费的大部分时间filter_entities用于布尔比较(创建key,而不是索引本身)。

\n\n

第二个注意事项:如果这种规模的性能对您很重要,那么在许多情况下,如果您需要以这种方式重复访问各个行,或者您是否可以更加矢量化,那么考虑更大的情况也是有用的。

\n