我之前的代码为我提供了一个有趣区域的参考列表边界的每个条目,以及另一个列表的索引。 例如,我有一个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)]
因此,对于我来说,这部分速度已经足够快了。有了Drecker和nakor的提示,它的速度仍然略快。现在的问题是我有样本的候选人,但我仍然必须执行以下任务:
sorted(key=my_fun)
来做到这一点,但这确实很耗时scipy.spatial.distance.cdist()
并检查了距离答案 0 :(得分:1)
使用直接切片:
arr = [values[border_pair[0]:border_pair[1]] for border_pair in borders]
如果values
是numpy数组,则速度至少会更快。
但是,这只是数据的简单副本,如果花费的时间太长(我认为),那么您就无法做很多事情。但是,如果这确实是瓶颈,也许您不需要复制所有这些数据,而是可以在values
数组中使用只读的格式?很难说,因为您在问题中没有提及您对他们的处理方式。
答案 1 :(得分:0)
为了补充Drecker的评论,我在计算机上进行了一些测试,如果values
是一个numpy数组,则在10,000x10,000矩阵上的速度大约是它的10倍:
# Generate random data
import numpy as np
N=10000
values = np.random.randint(0,100,[N,N]).astype(int)
borders = []
for _ in range(N):
inf = np.random.randint(0,99)
sup = np.random.randint(inf,100)
borders.append([inf,sup])
borders = np.array(borders)
In [1]: %time arr = [values[range(borders[i,0], borders[i,1])] for i in range(borders.shape[0])]
CPU times: user 7.97 s, sys: 7.27 s, total: 15.2 s
Wall time: 17.5 s
In [2]: %time arr=[values[borders[i,0]: borders[i,1]] for i in range(borders.shape[0])]
CPU times: user 30.7 ms, sys: 1.4 s, total: 1.43 s
Wall time: 1.43 s