Comment extraire une colonne d'un tableau multidimensionnel?


Réponses:


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

Voir aussi: "numpy.arange" et "remodeler" pour allouer de la mémoire

Exemple: (Allocation d'un tableau avec mise en forme de matrice (3x4))

nrows = 3
ncols = 4
my_array = numpy.arange(nrows*ncols, dtype='double')
my_array = my_array.reshape(nrows, ncols)

8
Cela m'a pris 2 heures pour découvrir [:, 2] devinez cette fonctionnalité pas dans la littérature officielle sur le tranchage?
niken

Que signifie la virgule?
Phil

3
@Phil [row, col]. la virgule se sépare.
AsheKetchum

11
Comment cette réponse peut-elle avoir autant de votes positifs? OP n'a jamais dit que c'était un tableau
engourdi

3
pour extraire 2 colonnes: A [:, [1,3]] par exemple extraire la deuxième et la quatrième colonne
sadalsuud

177

Serait-ce que vous utilisez un tableau NumPy ? Python a le module tableau , mais cela ne prend pas en charge les tableaux multidimensionnels. Les listes Python normales sont également unidimensionnelles.

Cependant, si vous avez une simple liste bidimensionnelle comme celle-ci:

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

alors vous pouvez extraire une colonne comme celle-ci:

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

Extraire la deuxième colonne (index 1):

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

Ou bien simplement:

>>> [row[1] for row in A]
[2, 6]

80

Si vous avez un tableau comme

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

Ensuite, vous extrayez la première colonne comme ça:

[row[0] for row in a]

Le résultat ressemble donc à ceci:

[1, 2, 3]

38

Vérifiez-le!

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

c'est la même chose que ci-dessus sauf que d'une manière ou d'une autre, il est plus propre le zip fait le travail mais nécessite des tableaux simples comme arguments, la syntaxe * a décompresse le tableau multidimensionnel en arguments de tableau unique


7
Qu'est-ce qui est dessus? N'oubliez pas que les réponses ne sont pas toujours triées de la même manière.
Muhd

2
C'est propre, mais ce n'est peut-être pas le plus efficace si les performances sont un problème, car il transpose toute la matrice.
IceArdor

6
Pour info, cela fonctionne en python 2, mais en python 3, vous obtiendrez un objet générateur, qui bien sûr n'est pas indexable.
Rishabh Agrahari

@RishabhAgrahari Quoi qu'il en soit pour faire ce zip dans Py3?
CtrlAltF2

2
@WarpDriveEnterprises yup, vous devrez convertir l'objet générateur en liste, puis faire l'indexation. exemple: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)

La fonction de carte en Python est une autre façon de procéder.


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

si vous voulez la deuxième colonne que vous pouvez utiliser

>>> x[:, 1]
array([ 1,  6, 11, 16])

1
Cela utilise numpy?
Forever

1
Je ne trouve aucune documentation pour arange()Python3 en dehors de numpy. N'importe qui?
Kevin W Matthews


9

L'opérateur itemgetter peut également vous aider, si vous aimez le python de style de réduction de carte, plutôt que les compréhensions de liste, pour un peu de variété!

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

1
utilisez itertools.imap pour les données volumineuses
Paweł Polewicz

L'approche itemgetter a fonctionné environ 50 fois plus vite que l'approche de compréhension de liste pour mon cas d'utilisation. Python 2.7.2, le cas d'utilisation comportait de nombreuses itérations sur une matrice avec quelques centaines de lignes et de colonnes.
joelpt

7

Vous pouvez également l'utiliser:

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

Remarque: cela ne fonctionne pas pour le tableau intégré et n'est pas aligné (par exemple, np.array ([[1,2,3], [4,5,6,7]]))


6

Je pense que vous voulez extraire une colonne d'un tableau tel qu'un tableau ci-dessous

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

Maintenant, si vous voulez obtenir la troisième colonne au format

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

Ensuite, vous devez d'abord faire du tableau une matrice

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

Et maintenant, vous pouvez faire des calculs par élément comme vous le feriez dans Excel.


1
Bien que cela m'a beaucoup aidé, je pense que la réponse peut être beaucoup plus courte: 1. A = np.array ([[1,2,3,4], [5,6,7,8], [9,10, 11,12]]) 2. Un tableau [:, 1] >> ([2, 6, 10])
Ufos

6

disons que nous avons une n X mmatrice ( nlignes et mcolonnes) disons 5 lignes et 4 colonnes

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

Pour extraire les colonnes en python, nous pouvons utiliser la compréhension de liste comme celle-ci

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

Vous pouvez remplacer 4 par le nombre de colonnes de votre matrice. Le résultat est

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


Cela crée-t-il une liste entièrement nouvelle?
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]

4

Une autre façon d'utiliser les matrices

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

3

Si vous avez un tableau à deux dimensions en Python (pas numpy), vous pouvez extraire toutes les colonnes comme ça,

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

L'exécution de ce code donnera,

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

Bien sûr, vous pouvez extraire une seule colonne par index (par exemple columns[0])


2

Bien que vous utilisiez zip(*iterable)pour transposer une liste imbriquée, vous pouvez également utiliser ce qui suit si les listes imbriquées varient en longueur:

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

résulte en:

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

La première colonne est donc:

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

2

Et bien un peu tard ...

Si les performances sont importantes et que vos données sont de forme rectangulaire, vous pouvez également les stocker dans une seule dimension et accéder aux colonnes par découpage régulier, par exemple ...

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]

La chose intéressante est que c'est vraiment rapide. Cependant , les indices négatifs ne fonctionnent pas ici! Vous ne pouvez donc pas accéder à la dernière colonne ou ligne par l'index -1.

Si vous avez besoin d'une indexation négative, vous pouvez régler un peu les fonctions d'accesseur, par exemple

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]

J'ai vérifié cette méthode et le coût de récupération de la colonne est bien moins cher que celui des boucles imbriquées. Cependant, réduire une matrice 2d à 1d coûte cher si la matrice est grande, disons 1000 * 1000.
Zhongjun 'Mark' Jin

2

Si vous voulez saisir plus d'une colonne, utilisez simplement slice:

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

2

Je préfère le conseil suivant: avoir la matrice nommée matrix_aet utiliser column_number, par exemple:

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]

1

Utilisez simplement transpose (), alors vous pouvez obtenir les colonnes aussi facilement que vous obtenez des lignes

matrix=np.array(originalMatrix).transpose()
print matrix[NumberOfColum]

0

Toutes les colonnes d'une matrice dans une nouvelle liste:

N = len(matrix) 
column_list = [ [matrix[row][column] for row in range(N)] for column in range(N) ]
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.