我已将此报告为pandas issues上的一个问题。与此同时,我在这里发布这个希望节省其他人的时间,以防他们遇到类似的问题。
在分析需要优化的进程时,我发现重命名列未就地提高 x120 的性能(执行时间)。分析表明这与垃圾收集有关(见下文)。
此外,通过避免 dropna 方法恢复了预期的性能。
以下简短示例演示了一个因子 x12:
import pandas as pd
import numpy as np
就地=真
%%timeit
np.random.seed(0)
r,c = (7,3)
t = np.random.rand(r)
df1 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
indx = np.random.choice(range(r),r/3, replace=False)
t[indx] = np.random.rand(len(indx))
df2 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
df = (df1-df2).dropna()
## inplace rename:
df.rename(columns={col:'d{}'.format(col) for col in df.columns}, inplace=True)
100 个循环,3 个循环中的最佳:每个循环 15.6 毫秒
第一个输出行%%prun
:
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.018 0.018 0.018 0.018 {gc.collect}
就地=假
%%timeit
np.random.seed(0)
r,c = (7,3)
t = np.random.rand(r)
df1 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
indx = np.random.choice(range(r),r/3, replace=False)
t[indx] = np.random.rand(len(indx))
df2 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
df = (df1-df2).dropna()
## avoid inplace:
df = df.rename(columns={col:'d{}'.format(col) for col in df.columns})
1000 次循环,3 次中的最佳:每个循环 1.24 毫秒
避免dropna
通过避免使用以下dropna
方法可以恢复预期的性能:
%%timeit
np.random.seed(0)
r,c = (7,3)
t = np.random.rand(r)
df1 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
indx = np.random.choice(range(r),r/3, replace=False)
t[indx] = np.random.rand(len(indx))
df2 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
#no dropna:
df = (df1-df2)#.dropna()
## inplace rename:
df.rename(columns={col:'d{}'.format(col) for col in df.columns}, inplace=True)
1000 个循环,3 个循环中的最佳:每个循环 865 µs
%%timeit
np.random.seed(0)
r,c = (7,3)
t = np.random.rand(r)
df1 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
indx = np.random.choice(range(r),r/3, replace=False)
t[indx] = np.random.rand(len(indx))
df2 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
## no dropna
df = (df1-df2)#.dropna()
## avoid inplace:
df = df.rename(columns={col:'d{}'.format(col) for col in df.columns})
1000 个循环,3 个循环中的最佳:每个循环 902 µs