Я сообщил об этом как о проблеме pandas. Тем временем я публикую это здесь, надеясь спасти других, если они столкнутся с подобными проблемами.
После профилирования процесса, который необходимо оптимизировать, я обнаружил, что переименование столбцов NOT 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 (функция)
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 мкс на петлю