我正在使用df.loc[(key1, key2)]
索引一个大型的多索引Pandas df。有时我会得到一个系列(如预期的那样),但其他时候我会得到一个dataframe。我试图隔离导致后者的情况,但到目前为止,我所能看到的是它与得到PerformanceWarning: indexing past lexsort depth may impact performance
警告相关。
我想复制它来发布在这里,但我不能生成另一个案例,给我同样的警告。这是我的尝试:
def random_dates(start, end, n=10):
start_u = start.value//10**9
end_u = end.value//10**9
return pd.to_datetime(np.random.randint(start_u, end_u, n), unit='s')
np.random.seed(0)
df = pd.DataFrame(np.random.random(3255000).reshape(465000,7)) # same shape as my data
df['date'] = random_dates(pd.to_datetime('1990-01-01'), pd.to_datetime('2018-01-01'), 465000)
df = df.set_index([0, 'date'])
df = df.sort_values(by=[3]) # unsort indices, just in case
df.index.lexsort_depth
> 0
df.index.is_monotonic
> False
df.loc[(0.9987185534991936, pd.to_datetime('2012-04-16 07:04:34'))]
# no warning
所以我的问题是:是什么原因导致此警告?如何人为诱导?
4条答案
按热度按时间yuvru6vn1#
TL;DR:您的索引未排序,这会严重影响性能。
使用
df.sort_index()
对DataFrame的索引进行排序,以解决警告并提高性能。实际上,我已经在我的文章中详细描述了这一点:Select rows in pandas MultiIndex DataFrame(在“问题3”下)。
为了繁殖,
您会注意到第二个级别没有正确排序。
现在,尝试索引特定的横截面:
您将看到
xs
的相同行为:由this timing test I once did支持的文档似乎表明,处理未排序的索引会导致速度减慢-索引是O(N)时间,而它可能/应该是O(1)。
如果你在切片之前对索引进行排序,你会注意到不同之处:
最后,如果想知道索引是否已排序,请使用
MultiIndex.is_lexsorted
进行检查。至于你的问题,如何诱导这种行为,简单地排列索引就足够了。如果你的索引是唯一的,这是可行的:
如果你的索引不是唯一的,先添加一个
cumcount
艾德级别,nwsw7zdq2#
根据pandas高级索引(排序多索引)
在更高维的对象上,如果其他轴具有MultiIndex,则可以按级别对它们进行排序
并且:
即使数据没有排序,索引也可以工作,但效率会很低**(并显示PerformanceWarning)**。它还会返回数据的副本而不是视图:
根据它们,您可能需要确保索引正确排序。
p4rjhz4m3#
系列与 Dataframe 输出:我也遇到了同样的问题,有时
df.loc[(index1, index2)]
的输出是一个系列,有时是一个 Dataframe 。我发现这是由重复的索引引起的。如果 Dataframe 有一些重复的索引,df.loc[(index1, index2)]
的输出是一个 Dataframe ,否则是一个系列。u7up0aaq4#
在我的案例中,PerformanceWarning:索引超过LexSort深度可能会影响DF上的重复索引的性能。
案例:尝试在每个sheetname的循环中读取带有pandas的excel文件
在具有重复索引的工作表中给出:性能警告:索引超过lexsort深度可能会影响性能