2017-11-16 3 views
1

배열 3 * 4에서 가장 높은 수와 가장 낮은 수를 삭제하려고합니다. 의 말을하자, 데이터는 다음과 같습니다 평균 계산에서 배열의 최대 및 최소 요소 제거

a=np.array([[1,4,5,10],[2,6,5,0],[3,9,9,0]]) 

그래서 나는이 같은 결과를 볼 것으로 예상 : deleted_data을 = [4,5], [2,5], [3]

당신에게 수 각 배열에서 최대 및 최소를 삭제하는 방법을 알려주십시오.


그렇게 할,이 (UPDATE) 좋아했다 :

이제
#to find out the max/min values: 
b = np.max(a,1) #max 
c = np.min(a,1) #min 

#creating dataset after deleting max & min 
d=(a!=b[:,None]) & (a!=c[:,None]) 
f=[i[j] for i,j in zip(a, d)] 

output: [array([8, 7, 7, 9, 9, 8]), array([8, 7, 8, 6, 8, 8]), array([9, 8, 9, 9, 8]), array([6, 7, 7, 6, 6, 7]), array([7, 7, 7, 7, 6])] 

내가 어떻게 목록 개체의 평균을 계산하는 확실하지 않다? 나는 각 배열의 평균을 계산하고 싶은, 그래서 나는이 시도했다 :

mean1=f.mean(axis=0) 

하지만 그것은 작동하지 않았다.

+0

(이상 만 보인다는 당신이 요구하는지 무엇을 할 수 있습니다). – user

+0

게시 된 솔루션 중 어느 것이 적합합니까? 그렇다면, 그 중 하나를 수락 고려하십시오? – Divakar

+0

죄송합니다! 나는이 웹 사이트에 익숙하지 않았다. 그리고 네, 최선의 대답을 받아 들였습니다. 고맙습니다. – user

답변

2

또 다른 방법은 방금

a_masked.mean() 
을 할 수있는 마스크되지 않은 요소의 평균을 원하는 경우가에서 Masked Array

import numpy.ma as ma 

mask = np.logical_or(a == a.max(1, keepdims = 1), a == a.min(1, keepdims = 1)) 
a_masked = ma.masked_array(a, mask = mask) 

을 사용하는 것입니다

또는 행의 평균을 수행 할 수도 있습니다

a_masked.mean(1).data 

또는 열 내가 얼마나 최대 값을 삭제하는 방법 몰랐다 그래서 파이썬 초보자입니다 @hpaulj

a_masked.mean(0).data 
+0

아래 내 의견 양식 반복 : 마스크 된 배열의 유일한 장점은 명확합니다. 중간 배열을 만드는 것은 아래처럼 인라인 (in-line) 계산보다 느리고 메모리 집약적 일 것이고, 그렇지 않다면 (무겁게 마스크 된 배열에서 많은 다른 연산을하기를 원할 때)'scipy.sparse' 배열은 훨씬 나아질 것입니다. –

1

파이썬 listremove 메서드를가집니다. 이 np.array(...)와 배열로 다시 설정 될 수

def foo(i,j,k): 
    il = i.tolist() 
    il.remove(j) 
    il.remove(k) 
    return il 

In [230]: [foo(i,j,k) for i,j,k in zip(a,b,c)] 
Out[230]: [[4, 5], [2, 5], [3, 9]] 

: 우리는 행에 대한 최소 및 최대 요소를 제거 할 수있는 유틸리티 함수와

. 이 경우 마지막 행의 9 중 하나만 제거되었습니다. 두 항목을 모두 제거한 경우 마지막 목록의 값은 1이고 결과를 2 차원 배열로 되돌릴 수 없습니다.

아마도 maxmin 대신 argmaxargmin을 사용할 수있는 순수 배열 방법을 제안 할 수있을 것입니다. 그러나 목록 접근 방식이 파이썬 초보자에게 더 좋은 출발점이라고 생각합니다.


배열 마스킹 방법

In [232]: bi = np.argmax(a,1) 
In [233]: ci = np.argmin(a,1) 
In [234]: bi 
Out[234]: array([3, 1, 1], dtype=int32) 
In [235]: ci 
Out[235]: array([0, 3, 3], dtype=int32) 

In [243]: mask = np.ones_like(a, bool) 
In [244]: mask[np.arange(3),bi]=False 
In [245]: mask[np.arange(3),ci]=False 
In [246]: mask 
Out[246]: 
array([[False, True, True, False], 
     [ True, False, True, False], 
     [ True, False, True, False]], dtype=bool) 

In [247]: a[mask] 
Out[247]: array([4, 5, 2, 5, 3, 9]) 
In [248]: _.reshape(3,-1) 
Out[248]: 
array([[4, 5], 
     [2, 5], 
     [3, 9]]) 

우리가 단지 하나 개의 최대 각 열에서 한 분을 삭제하면 다시이 좋다.


또 다른 마스킹 방법 : 이것은 마지막 행의 모든 ​​'9 년대를 제거 않습니다

In [257]: (a!=b[:,None]) & (a!=c[:,None]) 
Out[257]: 
array([[False, True, True, False], 
     [ True, False, True, False], 
     [ True, False, False, False]], dtype=bool) 
In [258]: a[(a!=b[:,None]) & (a!=c[:,None])] 
Out[258]: array([4, 5, 2, 5, 3]) 

. 그러나 행 분리를 유지하지는 않습니다.

이 가변 길이를 행 구조를 유지하고 있도록 :

In [259]: mask=(a!=b[:,None]) & (a!=c[:,None]) 
In [260]: [i[j] for i,j in zip(a, mask)] 
Out[260]: [array([4, 5]), array([2, 5]), array([3])] 
+0

이 작품! 이 코드를 사용했습니다 : b = np.max (a, 1) #max print (b) c = np.min (a, 1) #min print (c) d = (a! = b [:, 없음]) & = [i, j for zip (a, d)] 결과는 목록 개체로 표시됩니다. [array ([8, 7, 7, 배열 ([8, 7, 8, 6, 8, 8]), 배열 ([9, 8, 9, 9] , 6, 7]), 배열 ([7, 7, 7, 7, 6])]. 목록 개체의 평균을 어떻게 계산합니까? – user

0

@hpaulj 예측 된 바와 같이, 어레이 전용 방법이있다. 그리고 그것은 두더지입니다.한 라이너 :

a[np.arange(a.shape[0])[:, None], np.sort(np.argpartition(a, (0,-1), axis = 1)[:, 1:-1], axis = 1)] 

를 가자는 그 분해 :

y_ = np.argpartition(a, (0,-1), axis = 1)[:, 1:-1] 

argpartiton는 상기 0 번째 인덱스 (최소) 각 행의 -1 번째 (최대) 요소를 취하고 그들을 이동 처음과 마지막 위치는 repsectively. [:,1:-1]은 다른 모든 항목에 대해 색인을 생성합니다. 이제 argpartition 때로는 요소의 나머지 순서를 변경할 수 있습니다, 그래서

y = np.sort(y_ , axis = 1) 

우리는 다시 원래 버전 위치로 인덱스의 나머지 부분을 정렬합니다. 이제 원래 (m, n) = a.shape 배열에 대한 최대 및 최소 인덱스가 제거 된 y.shape -> (m, n-2) 개의 인덱스 배열이 있습니다.

이제 이것을 사용하려면 행 표시가 필요합니다.

x = np.arange(a.shape[0])[:, None] 

arange 그냥 m 행 인덱스를 제공합니다. 이 x.shape -> (a.shape[0],) -> (m,) 배열을 인덱스 배열에 브로드 캐스트하려면 [:, None]이 필요하고 x.shape -> (m, 1)이되어야합니다. 이제 m은 방송용으로 정렬되며 두 세트의 색인이 있습니다.

a[x, y] 

array([[4, 5], 
     [2, 5], 
     [3, 9]]) 
+0

감사합니다, @ 대니얼 F하지만이 중 하나를 삭제 가장 높고 낮은. 가장 높고 낮은 것을 어떻게 삭제할 수 있습니까? – user

+0

"모든"최고 및 최저는 무엇을 의미합니까? –

+0

에서 볼 수 있듯이 [3,9,9,0]에는 2 개의 9가 있습니다. – user

1

당신은 마스크와 두 단계로 행 당 max 또는 min을 할 수없는 요소의 평균의 최종 목적지를 얻을 수는 -

In [140]: a # input array 
Out[140]: 
array([[ 1, 4, 5, 10], 
     [ 2, 6, 5, 0], 
     [ 3, 9, 9, 0]]) 

In [141]: m = (a!=a.min(1,keepdims=1)) & (a!=a.max(1,keepdims=1)) 

In [142]: (a*m).sum(1)/m.sum(1).astype(float) 
Out[142]: array([ 4.5, 3.5, 3. ]) 

이 중간 창조의 혼란을 방지 NumPy 기능을 사용하기에 가장 편리한 데이터 형식이 아닌 비정형 배열.

성능 향상을 위해 (a*m).sum(1)np.einsum('ij,ij->i',a,m)으로 사용하려면 np.einsum을 사용하십시오. 더 큰 배열에

런타임 테스트 -

In [181]: np.random.seed(0) 

In [182]: a = np.random.randint(0,10,(5000,5000)) 

# @Daniel F' soln from https://stackoverflow.com/a/47325431/ 
In [183]: %%timeit 
    ...: mask = np.logical_or(a == a.max(1, keepdims = 1), a == a.min(1, keepdims = 1)) 
    ...: a_masked = ma.masked_array(a, mask = mask) 
    ...: out = a_masked.mean(1).data 
1 loop, best of 3: 251 ms per loop 

# Posted in here 
In [184]: %%timeit 
    ...: m = (a!=a.min(1,keepdims=1)) & (a!=a.max(1,keepdims=1)) 
    ...: out = (a*m).sum(1)/m.sum(1).astype(float) 
10 loops, best of 3: 165 ms per loop 

# Posted in here with additional einsum 
In [185]: %%timeit 
    ...: m = (a!=a.min(1,keepdims=1)) & (a!=a.max(1,keepdims=1)) 
    ...: out = np.einsum('ij,ij->i',a,m)/m.sum(1).astype(float) 
10 loops, best of 3: 124 ms per loop 
+0

참. Masked Arrays의 유일한 장점은 명확합니다. 중간 배열을 만드는 것은 위와 같은 인라인 (in-line) 계산보다 느리고 메모리 집약적입니다 (마스크 된 배열에서 많은 다른 연산을하기를 원할 것입니다).'scipy.sparse' 배열 더 나아질거야. –