【发布时间】:2019-11-05 23:50:32
【问题描述】:
我之前的代码为我提供了一个有趣区域的参考列表边界的每个条目以及另一个列表的索引。 例如,我有一个 listA,它应该分配给另一个 listB 中的值。对于每个条目,应该可以获得索引,所以这是有效的:
listA[:]-d/2 <= listB[indices to find] <= listA[:]+d/2
我通过列表理解解决了这个问题,并使用带有边界索引的 python 内置 range() 方法作为参数来获取所有必需的值。所以我遍历我的边界列表并生成一个包含所有索引的列表。所以例如:
borders[0,:] = [1,4] 变为 indices[0] = [1,2,3]。
arr = [values[range(borders[i,0], borders[i,1])] for i in range(borders.shape[0])]
它可以工作,但对于大型数据集来说太慢了。我发现列表理解是问题所在。有没有一种我可以使用的 numpy/pandas/... 方法,它是一种矩阵运算?
数据集类似如下:
no_points = 10000
no_groups = 3
meas_duration = 60
df_AT = pd.DataFrame(np.transpose([np.sort(np.random.rand(no_points)*meas_duration) for _ in range(no_groups)]), columns = ['AT {}'.format(i+1) for i in range(no_groups)])
df_TT = pd.DataFrame(np.transpose([np.random.rand(no_points) for _ in range(no_groups)]), columns = ['TT {}'.format(i+1) for i in range(no_groups)])
df = pd.concat([df_AT, df_TT], axis=1)
filterCoincidence(df, window=1e-3)
\\ 编辑 不幸的是,我仍在努力。我将复制一段代码:
# process coincidence
borders = [list() for _ in range(len(AT_cols)-1)]
test = np.empty((AT_df.shape[0],3), dtype=object)
test[:,0] = np.arange(AT_df.shape[0])
for i, [AT, TT] in enumerate(zip(AT_cols[np.where(AT_cols != AT_cols[used_ref])], TT_cols[np.where(AT_cols != AT_cols[used_ref])])):
AT_ix = np.argwhere(AT_cols == AT).flatten()[0]
neighbors_lower = np.searchsorted(AT_df[AT].values, AT_df[AT_cols[used_ref]]-window, side='left')
neighbors_upper = np.searchsorted(AT_df[AT].values, AT_df[AT_cols[used_ref]]+window, side='left')
borders[i] = np.transpose([neighbors_lower, neighbors_upper])
coinc_ix = np.where(np.diff(borders[i], axis=1).flatten() != 0)[0]
test[coinc_ix,i+1]=np.asarray([np.arange(borders[i][j][0], borders[i][j][1], dtype=int) for j in coinc_ix])
test = test[~np.any(pd.isnull(test), axis=1)]
所以现在这部分对于我的目的来说已经足够快了。有了德雷克和纳克的提示,速度还是稍快一些。问题是现在我有候选样本,但我仍然需要执行以下任务:
- 根据第一个标准对样本进行排序:哪个最相似?所以我必须比较运输时间和到达时间(AT 和 TT 两列)。我可以用
sorted(key=my_fun)来做,但这真的很耗时 - 检查是否所有样本都在时间窗口内。与参考数据相比,这已实现,但是来自两个非参考组的测量值是否也在时间窗口内?我可以通过在代码中仅使用 +- window/2 来简化问题,但这是一个非常强大的假设,因为参考测量值应始终位于时间窗口的中间。因此我使用了
scipy.spatial.distance.cdist()并检查了距离
【问题讨论】:
标签: python pandas numpy indexing