Gibt es eine Funktion in numpy, um dieses Array unten in der ersten Spalte zu gruppieren?
Ich konnte keine gute Antwort über das Internet finden ..
>>> a
array([[ 1, 275],
[ 1, 441],
[ 1, 494],
[ 1, 593],
[ 2, 679],
[ 2, 533],
[ 2, 686],
[ 3, 559],
[ 3, 219],
[ 3, 455],
[ 4, 605],
[ 4, 468],
[ 4, 692],
[ 4, 613]])
Gewünschte Ausgabe:
array([[[275, 441, 494, 593]],
[[679, 533, 686]],
[[559, 219, 455]],
[[605, 468, 692, 613]]], dtype=object)
Inspiriert von Eelco Hoogendoorns Bibliothek, jedoch ohne seine Bibliothek, und die Tatsache, dass die erste Spalte Ihres Arrays immer größer wird.
>>> np.split(a[:, 1], np.cumsum(np.unique(a[:, 0], return_counts=True)[1])[:-1])
[array([275, 441, 494, 593]),
array([679, 533, 686]),
array([559, 219, 455]),
array([605, 468, 692, 613])]
Ich habe nicht "Timeit", aber dies ist wahrscheinlich der schnellere Weg, um die Frage zu erreichen:
PS: Ich habe eine ähnliche Zeile geschrieben, weil ich die Ergebnisse von np.nonzero "gruppieren" musste:
>>> indexes, values = np.nonzero(...)
>>> np.split(values, np.cumsum(np.unique(indexes, return_counts=True)[1]))
Das Paket numpy_indexed (Disclaimer: Ich bin sein Autor) soll diese Lücke in numpy schließen. Alle Operationen in numpy-indexed sind vollständig vektorisiert, und bei der Erstellung dieser Bibliothek wurden keine O (n ^ 2) -Algorithmen beschädigt.
import numpy_indexed as npi
npi.group_by(a[:, 0]).split(a[:, 1])
Beachten Sie, dass es normalerweise effizienter ist, relevante Eigenschaften direkt über solche Gruppen zu berechnen (z. B. group_by (keys) .mean (values)), anstatt sie zuerst in ein list/jagged-Array zu teilen.
Numpy ist hier nicht sehr praktisch, da die gewünschte Ausgabe kein Array von Ganzzahlen ist (es ist ein Array von Listenobjekten).
Ich empfehle entweder die reine Python-Methode ...
from collections import defaultdict
%%timeit
d = defaultdict(list)
for key, val in a:
d[key].append(val)
10.7 µs ± 156 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
# result:
defaultdict(list,
{1: [275, 441, 494, 593],
2: [679, 533, 686],
3: [559, 219, 455],
4: [605, 468, 692, 613]})
... oder der Pandas Weg:
import pandas as pd
%%timeit
df = pd.DataFrame(a, columns=["key", "val"])
df.groupby("key").val.apply(pd.Series.tolist)
979 µs ± 3.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
# result:
key
1 [275, 441, 494, 593]
2 [679, 533, 686]
3 [559, 219, 455]
4 [605, 468, 692, 613]
Name: val, dtype: object
n = unique(a[:,0])
array( [ list(a[a[:,0]==i,1]) for i in n] )
ausgänge:
array([[275, 441, 494, 593], [679, 533, 686], [559, 219, 455],
[605, 468, 692, 613]], dtype=object)
Vereinfachung der Antwort von Vincent J one kann return_index = True
anstelle von return_counts = True
verwenden und die cumsum
entfernen
np.split(a[:,1], np.unique(idx,return_index = True)[1][1:])
Ausgabe
[array([275, 441, 494, 593]),
array([679, 533, 686]),
array([559, 219, 455]),
array([605, 468, 692, 613])]
wenn Sie X als Array von Elementen angeben, die Sie gruppieren möchten, und Y (1D-Array) als entsprechende Gruppen, führt die folgende Funktion die Gruppierung mit numpy durch:
def groupby(X, y):
y = np.asarray(y)
X = np.asarray(X)
y_uniques = np.unique(y)
return [X[y==yi] for yi in y_uniques]
Also gibt groupby(a[:,1], a[:,0])
[array([275, 441, 494, 593]), array([679, 533, 686]), array([559, 219, 455]), array([605, 468, 692, 613])]
zurück
Ich habe np.unique () gefolgt von np.extract () verwendet
unique = np.unique(a[:, 0:1])
answer = []
for element in unique:
present = a[:,0]==element
answer.append(np.extract(present,a[:,-1]))
print (answer)
[array([275, 441, 494, 593]), array([679, 533, 686]), array([559, 219, 455]), array([605, 468, 692, 613])]