我有这个独立的代码片段,应该是不言自明的:
import string
import itertools
import numpy as np
import timeit
index = list(itertools.product(range(100_000), string.ascii_uppercase))
df = pd.DataFrame(index, columns=['i', 'p'])
df['n'] = np.random.randn(len(df))
df_2 = df.set_index('i', drop=False)
df = df.set_index(['i', 'p'], drop=False)
print('One level multiindex loc', timeit.timeit(lambda: df.loc[1000], number=100))
print('Search by column', timeit.timeit(lambda: df[df.i == 1000], number=100))
print('Non unique index loc', timeit.timeit(lambda: df_2.loc[1000], number=100))
结果:
One level multiindex loc 0.8600521469925297
Search by column 0.23243567100143991
Non unique index loc 0.03276521500083618
我需要根据 i
的值(在本例中为 1000)获取行组,并且我正在研究不同的访问模式。我完全不明白的是,为什么通过 MultiIndex 的第一级查找如此缓慢?我理解 MultiIndex 的概念是因为如果您遵循层次结构,它会很快。
编辑结果因 pandas 版本而异,现在看起来 pandas 1.1.0 中的 MultiIndex 有一些问题。
以下是 0.25 的结果:
print('One level multiindex loc 1', timeit.timeit(lambda: df.loc[1000], number=10000))
print('One level multiindex loc 2', timeit.timeit(lambda: df.loc[(1000, ), :], number=10000))
print('Search by column', timeit.timeit(lambda: df[df.i == 1000], number=10000))
print('Non unique index loc', timeit.timeit(lambda: df_2.loc[1000], number=10000))
One level multiindex loc 1 3.5869441789999996
One level multiindex loc 2 4.696559950999983
Search by column 26.05316364800001
Non unique index loc 2.409704655000013
与 pandas==1.1.0
的 10000 次重复比较:
One level multiindex loc 1 74.58197712
One level multiindex loc 2 74.65480156499996
Search by column 26.241522830999997
Non unique index loc 0.5789623329999927
pandas==1.0.5
:
One level multiindex loc 1 75.16352942799999
One level multiindex loc 2 81.75229192099998
Search by column 25.121312993000004
Non unique index loc 2.481764503999983
最佳答案
我需要更新我的答案,因为一些额外的时间显示完全不同的结果:
import string
import itertools
import numpy as np
import timeit
index = list(itertools.product(range(100_000), string.ascii_uppercase))
df = pd.DataFrame(index, columns=['i', 'p'])
df['n'] = np.random.randn(len(df))
df_2 = df.set_index('i', drop=False)
df = df.set_index(['i', 'p'], drop=False)
df3 = df.copy().sort_index(level=0)
print('One level multiindex loc with tuple', timeit.timeit(lambda: df.loc[(1000, )], number=100))
print('One level multiindex loc', timeit.timeit(lambda: df.loc[1000], number=100))
print('Explicitly sorted one level multiindex loc', timeit.timeit(lambda: df3.loc[(1000, )], number=100))
print('Explicitly sorted one level multiindex loc with tuple', timeit.timeit(lambda: df3.loc[1000], number=100))
print('Search by column', timeit.timeit(lambda: df[df.i == 1000], number=100))
print('Non unique index loc', timeit.timeit(lambda: df_2.loc[1000], number=100))
# One level multiindex loc with tuple 0.05624850000003789
# One level multiindex loc 0.029734599999983402
# Explicitly sorted one level multiindex loc 0.03403290000005654
# Explicitly sorted one level multiindex loc with tuple 0.028620700000146826
# Search by column 0.5066366999999445
# Non unique index loc 0.0468722999999045
我的 Pandas pd.__version__ == 1.0.5
。
从版本 1.0.5 到 1.1.0 似乎有一些性能回归。
显式排序索引似乎可以提高索引速度,因此 MultiIndex loc
是最快的方法。我不知道内部发生了什么,但即使是未明确排序的 df.index
也会显示 df.index.get_level_values(0).is_monotonic_increasing
== True
,所以它应该像排序索引一样处理。也许 pandas 核心开发团队的某个人可以阐明一些问题?
关于python - Pandas MultiIndex 单级查找比其他访问模式慢得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63374659/