2017-11-16 3 views
1

Ich hoffe, die höchste Zahl und die niedrigste Zahl aus dem Array 3 * 4 zu löschen. Lassen Sie uns sagen, sieht die Daten wie folgt:Max- und Min-Elemente des Arrays aus der Mittelwertberechnung entfernen

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

so erwartete ich so das Ergebnis zu sehen: deleted_data = [4,5], [2,5], [3]

Könnten Sie beraten Sie mich, wie Sie die Max und Min aus jedem Array löschen?


, dies zu tun, habe ich so (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])] 

Jetzt bin ich nicht sicher, wie die Mittel der Liste Objekte zu berechnen? Ich möchte den Mittelwert jedes Array berechnen, so habe ich versucht, dies:

mean1=f.mean(axis=0) 

aber es hat nicht funktioniert.

+0

@hpaulj ich ein Python-Anfänger bin und so hatte ich keine Ahnung, wie die Maximalwerte zu löschen. – user

+0

Hat eine der veröffentlichten Lösungen für Sie funktioniert? Wenn ja, in Betracht ziehen, einen von denen zu akzeptieren? – Divakar

+0

Entschuldigung! Ich war mit dieser Website nicht vertraut. Und ja, ich habe die beste Antwort akzeptiert. Vielen Dank. – user

Antwort

2

Eine andere Methode ist es, ein 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) 

von dort zu verwenden, wenn Sie einen Durchschnitt der nicht maskierten Elemente möchten, können Sie einfach

a_masked.mean() 
tun

Oder Sie könnten sogar den Mittelwert der Zeilen

a_masked.mean(1).data 

oder Spalten (seltsam, aber scheint zu sein, was Sie fragen)

a_masked.mean(0).data 
+0

Wiederholen Sie mein Kommentarformular unten: Der einzige Vorteil von maskierten Arrays ist die Klarheit. Das Erstellen eines Intermediate-Arrays wird fast immer langsamer und speicherintensiver sein als In-Line-Berechnungen wie unten, und wenn dies nicht der Fall ist (dh Sie möchten viele verschiedene Operationen auf einem stark maskierten Array durchführen), "scipy.sparse" Arrays werden noch besser. –

1

Ein Python list hat eine remove Methode.

Mit einer Nutzenfunktion wir die MIN- und MAX-Elemente aus einer Reihe entfernen konnten:

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

Dieser zurück in ein Array mit np.array(...) gedreht werden kann. Beachten Sie, dass dies nur einen der 9 in der letzten Zeile entfernt. Wenn beide entfernt worden wären, hätte die letzte Liste nur einen Wert, und das Ergebnis konnte nicht in ein 2D-Array zurückverwandelt werden.

Ich bin sicher, dass wir mit einem reinen-Array-Verfahren kommen könnten, möglicherweise argmax und argmin statt max und min useing. Aber ich denke, dass der Listenansatz ein besserer Ausgangspunkt für einen Python-Anfänger ist.


Ein Array Maskieren Ansatz

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

Auch das ist besser, wenn wir nur aus jeder Zeile eine max und eine Minute löschen.


Ein anderer Maskierungs Ansatz:

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

Dies all ‚9s in der letzten Zeile nicht entfernt. Aber es behält die Zeilenaufteilung nicht bei.

Dies bewahrt die Zeilenstruktur und ermöglicht variable Längen:

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

Das funktioniert! Ich habe diesen Code verwendet: b = np.max (a, 1) #max drucken (b) c = np.min (a, 1) #min drucken (c) d = (a! = b [:, None]) & (a! = c [:, None]) f = [i [j] für i, j in zip (a, d)] aber das Ergebnis zeigt folgendes als Listenobjekt: [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])]. Wie kann ich den Mittelwert des Listenobjekts berechnen? – user

0

@hpaulj Wie vorausgesagt, es ist ein Array-only-Methode. Und es ist ein doozy.Als Einzeiler:

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

Lassen Sie uns das aufgliedern:

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

argpartiton nimmt den Index des 0 th (kleinste) und -1 th (größten) Elemente jeder Zeile und verschiebt sie in die erste und letzte Position. [:,1:-1] indiziert alles andere. Jetzt argpartition kann manchmal den Rest der Elemente neu anordnen, so

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

Wir sortieren den Rest der Indizes zurück in ihre ursprünglichen Positionen. Jetzt haben wir ein y.shape -> (m, n-2) Array von Indizes mit den Max und Min entfernt, für Ihre ursprüngliche (m, n) = a.shape Array.

Um dies zu verwenden, brauchen wir auch die Zeilenindizes.

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

arange gibt nur die m Zeilenindizes. Um dieses x.shape -> (a.shape[0],) -> (m,) Array zu Ihrem Index-Array zu übertragen, benötigen Sie [:, None], um x.shape -> (m, 1) zu machen. Jetzt die m richtet sich für die Ausstrahlung und Sie haben Ihre zwei Sätze von Indizes.

a[x, y] 

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

Danke, @Daniel F Aber das löschte nur einen höchsten und niedrigsten. Wie kann ich jede höchste und niedrigste löschen? – user

+0

was meinst du mit "jeder" höchsten und niedrigsten? –

+0

wie Sie sehen können gibt es zwei 9 in [3,9,9,0]. – user

1

Sie zum Endziel bekommen konnte von durchschnittlich Elemente, die nicht die max oder min pro Zeile in zwei Schritten mit Maskierung sind -

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

Dies vermeidet das Durcheinander der Zwischen Schaffung zackige Arrays, die nicht die bequemsten Datenformate für NumPy-Funktionen sind.

Alternativ zur Leistungssteigerung nutzen np.einsum das Äquivalent von (a*m).sum(1) mit np.einsum('ij,ij->i',a,m) zu bekommen.

Runtime-Test auf größere Array -

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

True. Der einzige Vorteil von Masked Arrays ist die Klarheit. Das Erstellen eines Intermediate-Arrays wird fast immer langsamer und speicherintensiver sein als In-Line-Berechnungen wie oben und wenn es nicht so ist (dh Sie wollen viele verschiedene Operationen auf einem stark maskierten Array durchführen), so genannte "scipy.sparse" -Arrays wird noch besser. –

Verwandte Themen