Python Pandas多索引单级查找比其他访问模式慢得多

Python Pandas多索引单级查找比其他访问模式慢得多,python,pandas,Python,Pandas,我有一段独立的代码片段,应该是不言自明的: 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.

我有一段独立的代码片段,应该是不言自明的:

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)的值获得一组行,并且我正在研究不同的访问模式。我绝对不明白的是,为什么多索引的第一级查找速度如此之慢?我理解了多重索引的概念,因为如果您遵循层次结构,它的速度很快

根据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
将熊猫==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
熊猫==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
我的熊猫
pd.\uuuuu版本=1.0.5

从1.0.5版到1.1.0版,性能似乎有所下降


对索引进行显式排序似乎可以提高索引速度,因此多索引
loc
是最快的方法。我不知道内部发生了什么,但即使是未显式排序的
df.index
也显示
df.index.get_level_值(0)。它是单调递增的
==True
,因此应该像排序索引一样处理它。也许pandas核心开发团队中的某个人可以透露一些信息?

hm该代码不会为我产生相同的结果:
print('One-level-multiindex loc 1',timeit.timeit(lambda:df.loc[1000],number=100])print('One-level-multiindex loc 2',timeit.timeit(lambda:df.loc[(1000,,:],number=100))
:0.7810162069945363,0.689672257998609这对我来说快了10%,但仍然是最慢的,顺序与原来的一样。可能与熊猫版本有关?这里是熊猫版本1.0.5。我对代码示例的计时也不同。可能是从1.0.5到1.1.0之间的某个性能回归?请检查我的编辑,结果是0.25与1.1.0非常不同。似乎是最近的一些变化造成的。是的,似乎是。。。感谢您添加编辑。查看pandas变更日志,一些多索引行为已恢复为pandas版本<0.23。。但是看到您安装了0.25,这似乎也不是原因。。。因此,至少我帮助找出了导致性能下降的原因