Вам обязательно нужно будет изменить свой входной массив, потому что вырезание «строк» из 3D-куба оставляет структуру, которая не может быть правильно решена.
Как у нас нет данных, я буду использовать другой пример первым, чтобы объяснить, как это работает возможное решение:
>>> import numpy as np
>>> from numpy.lib.stride_tricks import as_strided
>>>
>>> threshold = 18
>>> a = np.arange(5*3*2).reshape(5,3,2) # your dataset of 2000x2500x32
>>> # Taint the data:
... a[0,0,0] = 5
>>> a[a==22]=20
>>> print(a)
[[[ 5 1]
[ 2 3]
[ 4 5]]
[[ 6 7]
[ 8 9]
[10 11]]
[[12 13]
[14 15]
[16 17]]
[[18 19]
[20 21]
[20 23]]
[[24 25]
[26 27]
[28 29]]]
>>> a2 = a.reshape(-1, np.prod(a.shape[1:]))
>>> print(a2) # Will prove to be much easier to work with!
[[ 5 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 20 23]
[24 25 26 27 28 29]]
Как вы можете видеть, из приведенного выше представления, то это уже становится намного теперь яснее, из каких окон вы хотите вычислить пиковое значение. И вам понадобится эта форма, если вы собираетесь удалить «строки» (теперь они были преобразованы в столбцы) из этой структуры данных, чего вы не могли бы сделать в трех измерениях!
>>> isize = a.itemsize # More generic, in case you have another dtype
>>> slice_size = 4 # How big each continuous slice is over which the Peak2Peak value is calculated
>>> slices = as_strided(a2,
... shape=(a2.shape[0] + 1 - slice_size, slice_size, a2.shape[1]),
... strides=(isize*a2.shape[1], isize*a2.shape[1], isize))
>>> print(slices)
[[[ 5 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 20 23]]
[[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 20 23]
[24 25 26 27 28 29]]]
Так я принял, в качестве примера, размер окна из 4-х элементов: Если пик с пиковым значением в пределах любого из этих кусочков 4 элементов (в набор данных, так что каждый столбец) меньше определенный порог, Я хочу исключить его. Это можно сделать следующим образом:
>>> mask = np.all(slices.ptp(axis=1) >= threshold, axis=0) # These are the ones that are of interest
>>> print(a2[:,mask])
[[ 1 2 3 5]
[ 7 8 9 11]
[13 14 15 17]
[19 20 21 23]
[25 26 27 29]]
Теперь вы можете ясно видеть, что испорченные данные были удалены. Но помните, вы не могли просто удалить эти данные из 3D-массива (но тогда вы могли бы замаскировать его).
Очевидно, что вы должны будете установить threshold
к .01
в вашем сценарии использования, и slice_size
к 100
.
Опасайтесь, в то время как форма as_strided
является чрезвычайно эффективной с точки зрения памяти, вычисляя пиковые значения этого массива и сохраняя этот результат, требующий достаточного объема памяти в вашем случае: 1901x (2500x32) в сценарии полного случая, поэтому, когда вы не игнорируете первые 1000 ломтиков. В вашем случае, когда вы заинтересованы только в срезах от 1000:1900
, вы бы добавить, что в коде следующим образом:
mask = np.all(slices[1000:1900,:,:].ptp(axis=1) >= threshold, axis=0)
И что бы уменьшить объем памяти, необходимый для хранения этой маски «только» 900x (2500x32) (любого типа данных, который вы использовали).
Просьба уточнить: каков критерий для этих строк считаться плохим? Также «строки» в трехмерном контексте не имеют большого смысла. Вы имеете в виду последнюю ось, поэтому «строки» из 32 элементов? –
Я добавил функцию для обнаружения «плохой», а также уточнил, что я имею в виду строки из 2000 значений. Спасибо заранее за ваш интерес! – tix3
Информация, которую вы добавили о том, что должна делать ваша программа, не соответствует фактическому алгоритму: 'x [i * 100: (i + 1) * 100]' будет принимать (для первой итерации 'i') значения 'x [1000: 1100]'. Поэтому он даже не начинается с нуля. Вы уверены, что это было у вас в голове? –