pandas dataframe:loc vs query performance

Syn*_*ror 9 python indexing performance dataframe pandas

我在python中有2个数据帧,我想查询数据.

  • DF1:4M记录x 3列.查询功能接缝比loc功能更有效.

  • DF2:2K记录x 6列.loc函数接缝比查询函数更有效.

两个查询都返回单个记录.通过在循环中运行相同的操作10K次来完成模拟.

运行python 2.7和pandas 0.16.0

有什么建议可以提高查询速度吗?

jez*_*ael 15

为了提高性能,可以使用numexpr:

import numexpr

np.random.seed(125)
N = 40000000
df = pd.DataFrame({'A':np.random.randint(10, size=N)})

def ne(df):
    x = df.A.values
    return df[numexpr.evaluate('(x > 5)')]
print (ne(df))

In [138]: %timeit (ne(df))
1 loop, best of 3: 494 ms per loop

In [139]: %timeit df[df.A > 5]
1 loop, best of 3: 536 ms per loop

In [140]: %timeit df.query('A > 5')
1 loop, best of 3: 781 ms per loop

In [141]: %timeit df[df.eval('A > 5')]
1 loop, best of 3: 770 ms per loop
Run Code Online (Sandbox Code Playgroud)
import numexpr
np.random.seed(125)

def ne(x):
    x = x.A.values
    return x[numexpr.evaluate('(x > 5)')]

def be(x):
    return x[x.A > 5]

def q(x):
    return x.query('A > 5')

def ev(x):
    return x[x.eval('A > 5')]


def make_df(n):
    df = pd.DataFrame(np.random.randint(10, size=n), columns=['A'])
    return df


perfplot.show(
    setup=make_df,
    kernels=[ne, be, q, ev],
    n_range=[2**k for k in range(2, 25)],
    logx=True,
    logy=True,
    equality_check=False,  
    xlabel='len(df)')
Run Code Online (Sandbox Code Playgroud)

图形

  • 第二部分(图形代码)中的`ne`函数不会返回与其他函数相同的东西。每隔一个函数返回一个“ Pandas DataFrame”,而“ ne”返回一个“ numpy.Array”。当重写以匹配您在第一部分中使用的“ ne”函数时,它更接近于像“ be”那样的性能。您也可以通过像“ return return x [xAvalues> 5]` (6认同)
  • 我根据上面 @VictorUriarte 的评论,使用更正的“ne”和修改的“be”函数重新运行了测试,并编辑了答案以显示扩展图。 (2认同)

Raf*_*aga 9

python 3.9.5我添加了 .loc 函数并使用了 @jezrael 用于测试和中性能的相同代码pandas 1.2.5

import numpy as np
import pandas as pd
import numexpr
import perfplot
np.random.seed(125)

def ne(x):
    return x[numexpr.evaluate('(x > 5)')]

def bex(x):
    return x[x.A.values > 5]

def be(x):
    return x[x.A > 5]

def lc(x):
    return x.loc[x.A > 5]

def lcx(x):
    return x.loc[x.A.values > 5]

def q(x):
    return x.query('A > 5')

def ev(x):
    return x[x.eval('A > 5')]

def make_df(n):
    df = pd.DataFrame(np.random.randint(10, size=n), columns=['A'])
    return df


perfplot.show(
    setup=make_df,
    kernels=[ne, lc, lcx, be, bex, q, ev],
    n_range=[2**k for k in range(2, 25)],
    logx=True,
    logy=True,
    equality_check=False,  
    xlabel='len(df)')
Run Code Online (Sandbox Code Playgroud)

使用该.loc函数不会影响be函数的结果,直到 10^6 行,使用 te 列.values被认为是最快的选项。该query方法是最慢的。

前5

这里只是 loc 和 be,以查看重叠。 loc 与 be