我有一个相当大的 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 秒± 111 毫秒(平均 7 次运行的标准±,每次 1 次循环(
对列进行切片:
对每环 2.15 秒± 77.1 毫秒(7 次运行的平均标准±差,每次 1 次循环(
多索引进行切片比对列进行切片要慢得多。
这是预期的行为吗?有没有办法优化切片过程?
谢谢
我最终解决了将数据分组到其中一个索引中的问题,这使切片的速度提高了 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)