我已经在pandas issues上报告了这个问题。同时,我在这里发帖,希望能为其他人节省时间,以防他们遇到类似的问题。
在对需要优化的进程进行分析时,我发现重命名列不是inplace可以将执行时间提高x120。分析表明,这与垃圾回收有关(见下文)。
此外,避免使用dropna方法可以恢复预期的性能。
以下简短的示例展示了一个因子x12:
在对需要优化的进程进行分析时,我发现重命名列不是inplace可以将执行时间提高x120。分析表明,这与垃圾回收有关(见下文)。
此外,避免使用dropna方法可以恢复预期的性能。
以下简短的示例展示了一个因子x12:
import pandas as pd
import numpy as np
inplace=True
%%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}
inplace=False
%%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微秒
%%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微秒
.copy()
的建议确实解决了问题。感谢您详细而及时的回复! - eldad-adf.dropna().rename(....).sum()
非常直观/易读。当您使用inplace操作时,无法进行链式操作。 - Jeffsome_long_complicated_expression[some:long_slice, more_information_here] += 1
相对于some_long_complicated_expression[some:long_slice, more_information_here] = some_long_complicated_expression[some:long_slice, more_information_here] + 1
的优势的变体。 - DSM