我希望可以提出这类问题。
我有一个get_lags
函数,它接受一个数据框,对于每一列,将列移动到列表n_lags
中的每个n。因此,如果n_lags = [1, 2]
,该函数将每列一次移动一次,一次移动两个位置,以这种方式创建新的滞后列。
def get_lags (df, n_lags):
data =df.copy()
data_with_lags = pd.DataFrame()
for column in data.columns:
for i in range(n_lags[0], n_lags[-1]+1):
new_column_name = str(column) + '_Lag' + str(i)
data_with_lags[new_column_name] = data[column].shift(-i)
data_with_lags.fillna(method = 'ffill', limit = max(n_lags), inplace = True)
return data_with_lags
所以,如果:
df.columns
ColumnA
ColumnB
然后,get_lags(df, [1 , 2]).columns
将是:
ColumnA_Lag1
ColumnA_Lag2
ColumnB_Lag1
ColumnB_Lag2
问题:使用包含大约100,000行和20,000列的数据框,这需要永远运行。在一台16 GB的RAM,核心i7 windows机器上,一旦我等了15分钟才能运行代码,然后才停止它。无论如何我可以调整这个功能,使其更快?
答案 0 :(得分:1)
这可能不适用于您的情况(我希望我理解您正在尝试正确执行的操作),但您可以通过不首先执行此操作来大幅加速。您可以将列视为ring buffer吗?
不要在事后更改列,而是跟踪:
所以不要移动数据,而是执行以下操作:
current_column = (current_column + 1) % total_columns
然后写下该栏目。
答案 1 :(得分:1)
您需要shift
+ concat
。这是简洁版 -
def get_lags(df, n_lags):
return pd.concat(
[df] + [df.shift(i).add_suffix('_Lag{}'.format(i)) for i in n_lags],
axis=1
)
这是一个更友好的内存版本,使用for循环 -
def get_lags(df, n_lags):
df_list = [df]
for i in n_lags:
v = df.shift(i)
v.columns = v.columns + '_Lag{}'.format(i)
df_list.append(v)
return pd.concat(df_list, axis=1)