Pandas在索引上的性能切片与在列上切片的切片

时间:2018-03-12 13:25:34

标签: python python-3.x pandas slice

我有一个相当大的Pandas数据帧(30M行),我需要反复切片,因此性能至关重要。 切片需要在一列的值和另一列的值列表中完成。 我尝试了两种不同的方法,可以通过以下示例进行说明:

import numpy as np
import pandas as pd

df = pd.DataFrame(
    np.random.randint(1,1000,(10000000,4)),
    columns=['A','B','C','D']
).set_index(['A','B'])

# The values I'm looking for
index_a = np.random.randint(1,1000)  # One value
index_b = np.random.randint(1,1000,150)  # A list of values

# Slicing over the multi-index
idx = pd.IndexSlice
%timeit df.loc[idx[index_a, list(index_b)], :]

# Slicing over column values
df1 = df.reset_index()
%timeit df1.loc[(df1.A == index_a) & (df1.B.isin(index_b))]

在我的机器上,两种情况的表现都非常明显:

切片索引:

  

每回路3.92 s±111 ms(平均值±标准偏差,7次运行,每次1次循环)

切片列:

  

每循环2.15 s±77.1 ms(平均值±标准偏差,7次运行,每次循环1次)

对多列索引进行切片要比对列进行切片要慢得多。

这是预期的行为吗?有没有办法优化切片过程?

由于

1 个答案:

答案 0 :(得分:0)

我最终解决了我的问题,将其中一个索引中的数据分组,这使得切片的速度提高了10倍以上。 例如:

df_g = df.groupby(by='A')

def slice_it(ia, ib):
    tg = df_g.get_group(ia)
    return tg.loc[tg.B.isin(index_b)]

%timeit slice_it(index_a, index_b)