2015-01-24 3 views
0

조작 할 필요가있는 큰 3 차원 numpy (2000,2500,32) 배열이 있습니다. 일부 행이 잘못되어 여러 행을 삭제해야합니다. 행 검출하기 위해 는 "불량"I는 다음과 같은 기능이 0.01 미만의 피크 값과 피크 (100 개) 값의 범위가 2000 어떤 순서 나쁜 표시다차원 배열에서 행 제거

def badDetect(x): 
    for i in xrange(10,19): 
    ptp = np.ptp(x[i*100:(i+1)*100]) 
    if ptp < 0.01: 
     return True 
    return False 

를 사용하고있다. 이 경우 ([:, x, y]로 numpy에서 선택할 수있는) 2000 값의 시퀀스를 제거하고자 할 때 Numpy 삭제는 인덱스를 수락하는 것으로 보이지만 2 차원 배열에 대해서만 적용됩니다.

+0

구체적으로 말하자면,이 행이 나쁜 것으로 간주되는 기준은 무엇입니까? 또한 3D 컨텍스트의 "행"은별로 의미가 없습니다. 마지막 축을 의미합니까? 32 개 요소의 "행"? –

+0

"bad"를 탐지하는 기능을 추가했으며 2000 개의 값 행을 의미한다는 것을 분명히했습니다. 사전에 관심을 가져 주셔서 감사합니다! – tix3

+0

프로그램이 수행해야하는 것에 대해 추가 한 정보는 실제 알고리즘과 일치하지 않습니다 :'x [i * 100 : (i + 1) * 100]'은 (i의 첫 번째 반복을 위해) 값'x [1000 : 1100] '. 그래서 그것은 심지어 0에서 시작하지 않습니다. 당신이 이것을 염두에 두었던 방법이라고 확신합니까? –

답변

0

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]] 

: 우리가 데이터를 가지고 있지 않기 때문에

,이 가능한 솔루션이 어떻게 작동하는지 설명하기 위해 먼저 다른 예를 사용합니다 피크 투 피크 값을 계산할 창을 더 명확하게 나타냅니다. 그리고이 데이터 구조에서 3 차원에서 할 수없는 "행"(이제는 열로 변환되었습니다)을 제거하려는 경우이 양식이 필요합니다.

>>> 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]]] 

그래서 I는 예를 들어,했다 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_size100으로 설정해야합니다.

as_strided 양식은 매우 메모리 효율이 높지만이 배열의 최대 값을 계산하고 그 결과를 저장하는 데는 충분한 경우 메모리가 필요합니다 : 전체 시나리오에서는 1901x (2500x32) 그래서 당신이 처음 1000 개의 조각을 무시하지 않을 때. 당신이 1000:1900에서 조각에만 관심이 귀하의 경우에, 당신은과 같이 코드에 그를 추가해야합니다 :

mask = np.all(slices[1000:1900,:,:].ptp(axis=1) >= threshold, axis=0) 

을 그리고이 마스크를 저장하는 데 필요한 메모리를 줄일 것을 "전용" 900x (2500x32) 값 (사용중인 모든 데이터 유형)