性能警告:在没有 level 参数的情况下删除未排序的多索引可能会影响性能。如何摆脱它?

ING*_*0R1 6 python pandas

我有以下代码行

 end_df['Soma Internet'] = end_df.iloc[:,end_df.columns.get_level_values(1) == 'Internet'].drop('site',axis=1).sum(axis=1)
Run Code Online (Sandbox Code Playgroud)

它基本上通过特定的 1 级列过滤我的多索引 df 。删除一些不需要的列。并对所有其他项进行求和。

我浏览了一些文档和其他提出的问题。但我不太明白是什么原因导致了警告,而且我也很想重写这段代码,所以我摆脱了它。

use*_*849 9

让我们尝试一个例子(为了简单起见,没有数据):

import pandas as pd

# Column MultiIndex.
idx = pd.MultiIndex(levels=[['Col1', 'Col2', 'Col3'], ['subcol1', 'subcol2']], 
                    codes=[[2, 1, 0], [0, 1, 1]])

df = pd.DataFrame(columns=range(len(idx)))
df.columns = idx
print(df)
Run Code Online (Sandbox Code Playgroud)
    Col3    Col2    Col1
subcol1 subcol2 subcol2
Run Code Online (Sandbox Code Playgroud)

显然,该列MultiIndex未排序。我们可以通过以下方式检查:

print(df.columns.is_monotonic_increasing)
Run Code Online (Sandbox Code Playgroud)
False
Run Code Online (Sandbox Code Playgroud)

这很重要,因为如果索引已排序,Pandas 执行索引查找和其他操作的速度会更快,因为它可以使用假定排序顺序的操作并且速度更快。事实上,如果我们尝试删除一列:

df.drop('Col1', axis=1)
Run Code Online (Sandbox Code Playgroud)
PerformanceWarning: dropping on a non-lexsorted multi-index without a level parameter may impact performance.
  df.drop('Col1', axis=1)
Run Code Online (Sandbox Code Playgroud)

相反,如果我们在删除之前对索引进行排序,则警告就会消失:

print(df.sort_index(axis=1))

# Index is now sorted in lexicographical order.
    Col1    Col2    Col3
subcol2 subcol2 subcol1
Run Code Online (Sandbox Code Playgroud)
# No warning here.
df.sort_index(axis=1).drop('Col1', axis=1)
Run Code Online (Sandbox Code Playgroud)

编辑(参见评论):正如警告所示,当我们没有指定要删除列的级别时,就会发生这种情况。这是因为要删除该列,pandas 必须遍历整个索引(发生在这里)。通过指定它,我们不需要这样的遍历:

# Also no warning.
df.drop('Col1', axis=1, level=0)
Run Code Online (Sandbox Code Playgroud)

然而,一般来说,这个问题更多地与行索引相关,因为通常列多索引要小得多。但对于更大的索引和数据帧,一定要记住这一点。事实上,这与按索引切片和查找特别相关。在这些情况下,您希望对索引进行排序以获得更好的性能。

  • 只是出于好奇,你所说的 lexsorted 是什么意思?我问这个是因为当我在 drop 方法中确定列的级别时,错误消失了 .drop('Site',level=0) (2认同)