Wie extrahiert man eine Spalte aus einem mehrdimensionalen Array?

Antworten:

227
>>> import numpy as np
>>> A = np.array([[1,2,3,4],[5,6,7,8]])

>>> A
array([[1, 2, 3, 4],
    [5, 6, 7, 8]])

>>> A[:,2] # returns the third columm
array([3, 7])

Siehe auch: "numpy.arange" und "reshape", um Speicher zuzuweisen

Beispiel: (Zuweisen eines Arrays mit Formung der Matrix (3x4))

nrows = 3
ncols = 4
my_array = numpy.arange(nrows*ncols, dtype='double')
my_array = my_array.reshape(nrows, ncols)
Andre Luiz
quelle
8
Ich habe 2 Stunden gebraucht, um [:, 2] zu entdecken. Vermutung, dass diese Funktion nicht in der offiziellen Literatur zum Schneiden enthalten ist?
Niken
Was bedeutet das Komma?
Phil
3
@Phil [row, col]. Das Komma wird getrennt.
AsheKetchum
11
Wie kann diese Antwort so viele positive Stimmen haben? OP hat nie gesagt, dass es ein numpy Array ist
sziraqui
3
für Extrakt 2 Spalten: A [:, [1,3]] zum Beispiel Extrakt zweite und vierte Spalte
sadalsuud
176

Könnte es sein, dass Sie ein NumPy-Array verwenden ? Python verfügt über das Array- Modul, das jedoch keine mehrdimensionalen Arrays unterstützt. Normale Python-Listen sind ebenfalls eindimensional.

Wenn Sie jedoch eine einfache zweidimensionale Liste wie diese haben:

A = [[1,2,3,4],
     [5,6,7,8]]

Dann können Sie eine Spalte wie folgt extrahieren:

def column(matrix, i):
    return [row[i] for row in matrix]

Extrahieren der zweiten Spalte (Index 1):

>>> column(A, 1)
[2, 6]

Oder alternativ einfach:

>>> [row[1] for row in A]
[2, 6]
Martin Geisler
quelle
80

Wenn Sie ein Array wie haben

a = [[1, 2], [2, 3], [3, 4]]

Dann extrahieren Sie die erste Spalte folgendermaßen:

[row[0] for row in a]

Das Ergebnis sieht also so aus:

[1, 2, 3]
Andrei Arsenin
quelle
38

Hör zu!

a = [[1, 2], [2, 3], [3, 4]]
a2 = zip(*a)
a2[0]

Es ist dasselbe wie oben, außer dass es irgendwie ordentlicher ist, dass die Zip-Datei die Arbeit erledigt, aber einzelne Arrays als Argumente benötigt. Die Syntax * a entpackt das mehrdimensionale Array in einzelne Array-Argumente

Mac D.
quelle
7
Was ist oben? Denken Sie daran, dass die Antworten nicht immer gleich sortiert sind.
Muhd
2
Dies ist sauber, aber möglicherweise nicht die effizienteste, wenn die Leistung ein Problem darstellt, da die gesamte Matrix transponiert wird.
IceArdor
6
Zu Ihrer Information, dies funktioniert in Python 2, aber in Python 3 erhalten Sie ein Generatorobjekt, das natürlich nicht abonnierbar ist.
Rishabh Agrahari
@RishabhAgrahari Wie auch immer, um diesen Zip in Py3 zu machen?
CtrlAltF2
2
@WarpDriveEnterprises yup, Sie müssen das Generatorobjekt in eine Liste konvertieren und dann die Subskription durchführen. Beispiel:a2 = zip(*a); a2 = list(a2); a2[0]
Rishabh Agrahari
14
def get_col(arr, col):
    return map(lambda x : x[col], arr)

a = [[1,2,3,4], [5,6,7,8], [9,10,11,12],[13,14,15,16]]

print get_col(a, 3)

Die Kartenfunktion in Python ist ein weiterer Weg.

Peter Paul
quelle
11
>>> x = arange(20).reshape(4,5)
>>> x array([[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9],
        [10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19]])

Wenn Sie die zweite Spalte möchten, können Sie verwenden

>>> x[:, 1]
array([ 1,  6, 11, 16])
simomod
quelle
1
Dies verwendet numpy?
foreever
1
Ich kann keine Dokumentation für arange()in Python3 außerhalb von numpy finden. Jemand?
Kevin W Matthews
10
[matrix[i][column] for i in range(len(matrix))]
Renatov
quelle
9

Der Itemgetter-Operator kann auch helfen, wenn Sie Python mit Kartenreduzierung anstelle von Listenverständnis für ein wenig Abwechslung mögen!

# tested in 2.4
from operator import itemgetter
def column(matrix,i):
    f = itemgetter(i)
    return map(f,matrix)

M = [range(x,x+5) for x in range(10)]
assert column(M,1) == range(1,11)
Gregg Lind
quelle
1
Verwenden Sie itertools.imap für große Datenmengen
Paweł Polewicz
Der Itemgetter-Ansatz lief ungefähr 50x schneller als der Listenverständnisansatz für meinen Anwendungsfall. Der Anwendungsfall von Python 2.7.2 bestand aus vielen Iterationen in einer Matrix mit einigen hundert Zeilen und Spalten.
Joelpt
7

Sie können dies auch verwenden:

values = np.array([[1,2,3],[4,5,6]])
values[...,0] # first column
#[1,4]

Hinweis: Dies funktioniert nicht für eingebaute Arrays und ist nicht ausgerichtet (z. B. np.array ([[1,2,3], [4,5,6,7]]).

Sergey
quelle
6

Ich denke, Sie möchten eine Spalte aus einem Array wie einem Array unten extrahieren

import numpy as np
A = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])

Nun, wenn Sie die dritte Spalte im Format erhalten möchten

D=array[[3],
[7],
[11]]

Dann müssen Sie zuerst das Array zu einer Matrix machen

B=np.asmatrix(A)
C=B[:,2]
D=asarray(C)

Und jetzt können Sie elementweise Berechnungen durchführen, ähnlich wie Sie es in Excel tun würden.

danielinthelionsden
quelle
1
Dies hat mir zwar sehr geholfen, aber ich denke, die Antwort kann viel kürzer sein: 1. A = np.array ([[1,2,3,4], [5,6,7,8], [9,10, 11,12]]) 2. Ein [:, 1] >> Array ([2, 6, 10])
Ufos
6

Nehmen wir an, wir haben eine n X mMatrix ( nZeilen und mSpalten) mit 5 Zeilen und 4 Spalten

matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16],[17,18,19,20]]

Um die Spalten in Python zu extrahieren, können wir das Listenverständnis wie folgt verwenden

[ [row[i] for row in matrix] for in range(4) ]

Sie können 4 durch eine beliebige Anzahl von Spalten in Ihrer Matrix ersetzen. Das Ergebnis ist

[ [1,5,9,13,17],[2,10,14,18],[3,7,11,15,19],[4,8,12,16,20] ]

Serge_k
quelle
Erstellt dies eine völlig neue Liste?
Kevin W Matthews
5
array = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]

col1 = [val[1] for val in array]
col2 = [val[2] for val in array]
col3 = [val[3] for val in array]
col4 = [val[4] for val in array]
print(col1)
print(col2)
print(col3)
print(col4)

Output:
[1, 5, 9, 13]
[2, 6, 10, 14]
[3, 7, 11, 15]
[4, 8, 12, 16]
Lee
quelle
4

Ein weiterer Weg mit Matrizen

>>> from numpy import matrix
>>> a = [ [1,2,3],[4,5,6],[7,8,9] ]
>>> matrix(a).transpose()[1].getA()[0]
array([2, 5, 8])
>>> matrix(a).transpose()[0].getA()[0]
array([1, 4, 7])
Shashwat
quelle
3

Wenn Sie in Python ein zweidimensionales Array haben (nicht numpy), können Sie alle Spalten wie folgt extrahieren:

data = [
['a', 1, 2], 
['b', 3, 4], 
['c', 5, 6]
]

columns = list(zip(*data))

print("column[0] = {}".format(columns[0]))
print("column[1] = {}".format(columns[1]))
print("column[2] = {}".format(columns[2]))

Das Ausführen dieses Codes ergibt Folgendes:

>>> print("column[0] = {}".format(columns[0]))
column[0] = ('a', 'b', 'c')

>>> print("column[1] = {}".format(columns[1]))
column[1] = (1, 3, 5)

>>> print("column[2] = {}".format(columns[2]))
column[2] = (2, 4, 6)

Natürlich können Sie eine einzelne Spalte von Index extrahieren (zB columns[0])

Russell
quelle
2

Trotz der Verwendung zip(*iterable)zum Transponieren einer verschachtelten Liste können Sie auch Folgendes verwenden, wenn die Länge der verschachtelten Listen variiert:

map(None, *[(1,2,3,), (4,5,), (6,)])

Ergebnisse in:

[(1, 4, 6), (2, 5, None), (3, None, None)]

Die erste Spalte lautet also:

map(None, *[(1,2,3,), (4,5,), (6,)])[0]
#>(1, 4, 6)
Lorenz Lo Sauer
quelle
2

Na ein bisschen spät ...

Wenn es auf die Leistung ankommt und Ihre Daten rechteckig sind, können Sie sie auch in einer Dimension speichern und durch regelmäßiges Schneiden auf die Spalten zugreifen, z.

A = [[1,2,3,4],[5,6,7,8]]     #< assume this 4x2-matrix
B = reduce( operator.add, A ) #< get it one-dimensional

def column1d( matrix, dimX, colIdx ):
  return matrix[colIdx::dimX]

def row1d( matrix, dimX, rowIdx ):
  return matrix[rowIdx:rowIdx+dimX] 

>>> column1d( B, 4, 1 )
[2, 6]
>>> row1d( B, 4, 1 )
[2, 3, 4, 5]

Das Schöne ist, dass dies sehr schnell geht. Jedoch negative Indizes funktionieren hier nicht! Sie können also nicht über den Index -1 auf die letzte Spalte oder Zeile zugreifen.

Wenn Sie eine negative Indizierung benötigen, können Sie die Accessor-Funktionen ein wenig optimieren, z

def column1d( matrix, dimX, colIdx ):
  return matrix[colIdx % dimX::dimX]

def row1d( matrix, dimX, dimY, rowIdx ):
  rowIdx = (rowIdx % dimY) * dimX
  return matrix[rowIdx:rowIdx+dimX]
Zappotek
quelle
Ich habe diese Methode überprüft und die Kosten für das Abrufen von Spalten sind weitaus günstiger als für verschachtelte Schleifen. Das Reduzieren einer 2d-Matrix auf 1d ist jedoch teuer, wenn die Matrix groß ist, beispielsweise 1000 * 1000.
Zhongjun 'Mark' Jin
2

Wenn Sie mehr als nur eine Spalte erfassen möchten, verwenden Sie einfach Slice:

 a = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
    print(a[:, [1, 2]])
[[2 3]
[5 6]
[8 9]]
Molina12
quelle
2

Ich bevorzuge den nächsten Hinweis: Die Matrix benennen matrix_aund verwenden column_number, zum Beispiel:

import numpy as np
matrix_a = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
column_number=2

# you can get the row from transposed matrix - it will be a column:
col=matrix_a.transpose()[column_number]
Vik Ermolenko
quelle
1

Verwenden Sie einfach transpose (), dann können Sie die Spalten so einfach wie Zeilen erhalten

matrix=np.array(originalMatrix).transpose()
print matrix[NumberOfColum]
David Tatis
quelle
0

Alle Spalten aus einer Matrix in eine neue Liste:

N = len(matrix) 
column_list = [ [matrix[row][column] for row in range(N)] for column in range(N) ]
user136036
quelle