Мой предыдущий код предоставляет мне для каждой записи границ списка ссылок интересующего региона с индексами другого списка.
Так, например, у меня есть 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)
\\ edit
К сожалению, я все еще работаю над этим. Я просто скопирую часть своего кода:
# 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()
и проверил расстояния