Çok boyutlu bir diziden bir sütunu nasıl çıkarırsınız?


Yanıtlar:


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

Ayrıca bkz: bellek ayırmak için "numpy.arange" ve "yeniden şekillendirme"

Örnek: (Bir diziyi matris (3x4) şekillendirme ile ayırma)

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

8
Keşfetmek için bana 2 saat sürdü [:, 2] dilimleme resmi literatürde değil bu özelliği tahmin?
niken

Virgül ne anlama geliyor?
Phil

3
@Phil [row, col]. virgül ayrılır.
AsheKetchum

11
Bu cevabın bu kadar çok oyu nasıl olabilir? OP asla numpy dizi olduğunu söyledi
sziraqui

3
ekstre 2 sütun için: A [:, [1,3]] örneğin ikinci ve dördüncü sütunu çıkar
sadalsuud

177

NumPy dizisi kullanıyor olabilir misiniz ? Python'un dizi modülü vardır, ancak bu çok boyutlu dizileri desteklemez. Normal Python listeleri de tek boyutludur.

Ancak, böyle iki boyutlu basit bir listeniz varsa:

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

o zaman böyle bir sütun çıkarabilirsiniz:

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

İkinci sütunu çıkarma (dizin 1):

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

Veya alternatif olarak, basitçe:

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

80

Şunun gibi bir diziniz varsa:

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

Sonra ilk sütunu şöyle çıkarırsınız:

[row[0] for row in a]

Sonuç şöyle görünür:

[1, 2, 3]

38

bunu kontrol et!

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

yukarıdaki gibi aynı şeydir, ancak bir şekilde zip işini yapar, ancak bağımsız değişkenler olarak tek diziler gerektirir, * bir sözdizimi çok boyutlu diziyi tek dizi bağımsız değişkenlerine açar


7
Yukarıda ne var? Yanıtların her zaman aynı şekilde sıralanmadığını unutmayın.
Muhd

2
Bu temizdir, ancak performans bir endişe ise tüm matrisi aktardığı için en etkili olmayabilir.
IceArdor

6
FYI, bu python 2'de çalışıyor, ancak python 3'te, elbette abonelikli olmayan jeneratör nesnesi alacaksınız.
Rishabh Agrahari

@RishabhAgrahari Bu zip dosyasını Py3'te yapmak nasıl?
CtrlAltF2

2
@WarpDriveEnterprises Evet, jeneratör nesnesini listeye dönüştürmeniz ve ardından aboneliği yapmanız gerekir. örnek: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)

Python'da harita fonksiyonu gitmek için başka bir yoldur.


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

ikinci sütunu istiyorsanız kullanabilirsiniz

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

1
Bu numpy kullanıyor?
Foreever

1
arange()Numpy dışında Python3 için herhangi bir belge bulamıyorum . Kimse?
Kevin W Matthews


9

Itemgetter operatörü de liste anlayışları yerine harita azaltma tarzı python isterseniz, biraz çeşitlilik için yardımcı olabilir!

# 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
büyük veriler için itertools.imap kullanın
Paweł Polewicz

İtemgetter yaklaşımı, kullanım durumum için liste kavrama yaklaşımından yaklaşık 50 kat daha hızlı koştu. Python 2.7.2, kullanım örneği, birkaç yüz satır ve sütun içeren bir matris üzerinde çok sayıda yinelemeydi.
Mart'ta joelpt

7

Bunu da kullanabilirsiniz:

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

Not: Bu yerleşik dizi için çalışmıyor ve hizalanmamış (örneğin np.array ([[1,2,3], [4,5,6,7]]))


6

Bence aşağıdaki gibi bir dizi bir sütun ayıklamak istiyorum

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

Şimdi üçüncü sütunu biçiminde almak istiyorsanız

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

O zaman önce diziyi bir matris yapmanız gerekir

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

Ve şimdi excel'de yaptığınız gibi element bilge hesaplamaları yapabilirsiniz.


1
Bu bana çok yardımcı oldu, ancak cevap çok daha kısa olabilir: 1. A = np.array ([[1,2,3,4], [5,6,7,8], [9,10, 11,12]]) 2. A [:, 1] >> dizi ([2, 6, 10])
Ufos

6

diyelim ki n X mmatrisimiz var ( nsatırlar ve msütunlar) 5 satır ve 4 sütun diyelim

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

Python'daki sütunları çıkarmak için, liste kavrayışını şu şekilde kullanabiliriz

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

Matrisinizin sahip olduğu sütun sayısını 4 ile değiştirebilirsiniz. Sonuç

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


Bu tamamen yeni bir liste oluşturuyor mu?
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

Matris kullanmanın bir yolu daha

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

Python'da (numpy değil) iki boyutlu bir diziniz varsa, böyle tüm sütunları ayıklayabilirsiniz,

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

Bu kodun çalıştırılması,

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

Tabii ki, tek bir sütunu dizine göre ayıklayabilirsiniz (örn. columns[0])


2

zip(*iterable)Yuvalanmış bir listeyi aktarmak için kullanılmasına rağmen , yuvalanmış listelerin uzunluğu değişiyorsa aşağıdakileri de kullanabilirsiniz:

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

sonuç:

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

İlk sütun böyledir:

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

2

Peki 'biraz' geç ...

Performansın önemli olması ve verilerinizin dikdörtgen şeklinde olması durumunda, bunu bir boyutta saklayabilir ve düzenli dilimleme gibi sütunlara erişebilirsiniz ...

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]

Temiz şey, bu gerçekten hızlı. Ancak , negatif dizinler burada çalışmaz! Böylece dizin -1'e göre son sütuna veya satıra erişemezsiniz.

Negatif indekslemeye ihtiyacınız varsa, erişimci işlevlerini biraz ayarlayabilirsiniz;

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]

Bu yöntemi kontrol ettim ve sütun alma maliyeti döngüler için iç içe olandan çok daha ucuz. Bununla birlikte, eğer matris büyükse, 2d matrisin 1d'ye düşürülmesi pahalıdır, örneğin 1000 * 1000.
Zhongjun 'Mark' Jin

2

Sadece bir sütundan daha fazlasını almak istiyorsanız sadece dilim kullanın:

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

2

Ben sonraki ipucu tercih: adlandırılmış matrix_ave kullanımı matris olması, column_numberörneğin:

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

Sadece transpose () kullanın, sonra sütunları satır aldığınız kadar kolay alabilirsiniz

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

0

Bir matristeki tüm sütunlar yeni bir listeye:

N = len(matrix) 
column_list = [ [matrix[row][column] for row in range(N)] for column in range(N) ]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.