索引Numpy矩阵最有效的方法是什么



问题:使用Pandas数据帧实现以下等效项的最有效方法是什么:按比例使用temp = df[df.feature] == value](有关上下文re:scale,请参阅下文)?

背景:我有大约500个实体30年的每日时间序列数据,对于每个实体和每一天,需要基于各种回顾创建90个特征,过去最多240天。目前,我每天都在循环,处理当天的所有数据,然后将其插入到预先分配的numpy矩阵中——但事实证明,就我的数据集大小而言,这非常慢。

天真的方法:

df = pd.DataFrame()
for day in range(241, t_max):
temp_a = df_timeseries[df_timeseries.t] == day].copy()
temp_b = df_timeseries[df_timeseries.t] == day - 1].copy()
new_val = temp_a.feature_1/temp_b.feature_1
new_val['t'] = day
new_val['entity'] = temp_a.entity
df.concat([df, new_val])

当前方法(简化):

df = np.matrix(np.zeros([num_days*num_entities, 3]))
col_dict = dict(zip(df_timeseries.columns, list(range(0,len(df_timeseries.columns)))))
mtrx_timeseries = np.matrix(df_timeseries.to_numpy())
for i, day in enumerate(range(241, t_max)):
interm = np.matrix(np.zeros([num_entities, 3]))
interm[:, 0] = day
temp_a = mtrx_timeseries[np.where(mtrx_timeseries[:, col_dict['t']] == day)[0], :]
temp_b = mtrx_timeseries[np.where(mtrx_timeseries[:, col_dict['t']] == day - 1)[0], :]
temp_cr = temp_a[:, col_dict['feature_1']]/temp_b[:, col_dict['feature_1']] - 1
temp_a = mtrx_timeseries[np.where(mtrx_timeseries[:, col_dict['t']] == day - 5)[0], :]                
temp_b = mtrx_timeseries[np.where(mtrx_timeseries[:, col_dict['t']] == t - 10)[0], :]

temp_or = temp_a[:, col_dict['feature_1']]/temp_b[:, col_dict['feature_1']] - 1
interm[:, 1:] = np.concatenate([temp_cr, temp_or], axis=1)
df[i*num_entities : (i + 1)*num_entities, :] = interm

对我所拥有的代码的完整版本进行的行分析显示,形式为mtrx_timeseries[np.where(mtrx_timeseries[:, col_dict['t']] == day)[0], :]的每条语句总共占用了大约23%的运行时间,因此我正在寻找一个更精简的解决方案。由于索引花费的时间最多,而且循环意味着每次迭代都要执行此操作,因此一种解决方案可能是只索引一次,将每天的数据存储在一个单独的数组元素中,然后在数组元素中循环?

这不是一个完整的问题解决方案,但我认为它会让你达到你需要的地方。

考虑以下代码:

entity_dict = {}
entity_idx = 0
arr = np.zeros((num_entities, t_max-240))
for entity, day, feature in df_timeseries[['entity', 'day', 'feature_1']].values:
if entity not in entity_dict:
entity_dict[entity] = entity_idx
entity_idx += 1
arr[entity_dict[entity], day-240] = feature

这将非常有效地将df_timeseries转换为由实体组织的num_entities*num_days形状的阵列。你根本不需要做任何花哨的索引。对numpy数组或矩阵进行索引的最有效方法是提前知道需要什么索引,而不是搜索数组为他们。然后您可以执行数组操作(在我看来,您的操作是简单的按元素划分,您可以在几行中完成,而不需要额外的循环)。

然后转换回原始格式。

相关内容

最新更新