Làm thế nào để bạn trích xuất một cột từ một mảng đa chiều?


Câu trả lời:


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

Xem thêm: "numpy.arange" và "định hình lại" để phân bổ bộ nhớ

Ví dụ: (Phân bổ một mảng với định hình ma trận (3x4))

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

8
Mất 2 giờ để khám phá [:, 2] đoán tính năng này không có trong tài liệu chính thức về cắt lát?
niken

Dấu phẩy có nghĩa là gì?
Phil

3
@Phil [row, col]. dấu phẩy tách ra.
AsheKetchum

11
Làm thế nào câu trả lời này có thể có rất nhiều upvote? OP không bao giờ nói đó là một mảng khó chịu
sziraqui

3
để trích xuất 2 cột: A [:, [1,3]] ví dụ trích xuất cột thứ hai và thứ tư
sadalsuud

176

Có thể là bạn đang sử dụng một mảng NumPy ? Python có mô-đun mảng , nhưng điều đó không hỗ trợ mảng đa chiều. Danh sách Python bình thường cũng là một chiều.

Tuy nhiên, nếu bạn có một danh sách hai chiều đơn giản như thế này:

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

sau đó bạn có thể trích xuất một cột như thế này:

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

Trích xuất cột thứ hai (chỉ mục 1):

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

Hoặc cách khác, đơn giản là:

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

80

Nếu bạn có một mảng như

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

Sau đó, bạn trích xuất cột đầu tiên như thế:

[row[0] for row in a]

Vì vậy, kết quả trông như thế này:

[1, 2, 3]

38

kiểm tra xem nó ra

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

nó cũng giống như trên, ngoại trừ bằng cách nào đó, nó gọn gàng hơn, zip thực hiện công việc nhưng yêu cầu các mảng đơn làm đối số, cú pháp * giải nén mảng đa chiều thành các đối số mảng đơn


7
Trên đây là gì? Hãy nhớ rằng các câu trả lời không phải lúc nào cũng được sắp xếp theo cùng một cách.
Muhd

2
Điều này là rõ ràng, nhưng có thể không hiệu quả nhất nếu hiệu suất là một mối quan tâm, vì nó đang hoán chuyển toàn bộ ma trận.
IceArdor

6
FYI, điều này hoạt động trong python 2, nhưng trong python 3, bạn sẽ nhận được đối tượng trình tạo, mà đối tượng không thể đăng ký được.
Rishabh Agrahari

@RishabhAgrahari Dù sao để làm zip này trong Py3?
CtrlAltF2

2
@WarpDrive ngoai yup, bạn sẽ phải chuyển đổi đối tượng trình tạo thành danh sách và sau đó thực hiện đăng ký. ví dụ: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)

chức năng bản đồ trong Python là một cách khác để đi.


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

nếu bạn muốn cột thứ hai bạn có thể sử dụng

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

1
Đây là sử dụng numpy?
Trước

1
Tôi không thể tìm thấy bất kỳ tài liệu nào cho arange()Python3 ngoài numpy. Bất kỳ ai?
Kevin W Matthews


9

Toán tử itemgetter cũng có thể giúp, nếu bạn thích python kiểu giảm bản đồ, thay vì hiểu danh sách, cho một chút đa dạng!

# 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
sử dụng itertools.imap cho dữ liệu lớn
Paweł Polewicz

Cách tiếp cận itemgetter chạy nhanh hơn khoảng 50 lần so với cách tiếp cận hiểu danh sách cho trường hợp sử dụng của tôi. Python 2.7.2, ca sử dụng là rất nhiều lần lặp trên một ma trận với vài trăm hàng và cột.
tham gia

7

Bạn cũng có thể sử dụng điều này:

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

Lưu ý: Điều này không hoạt động đối với mảng tích hợp và không được căn chỉnh (ví dụ: np.array ([[1,2,3], [4,5,6,7]]))


6

Tôi nghĩ rằng bạn muốn trích xuất một cột từ một mảng như một mảng bên dưới

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

Bây giờ nếu bạn muốn lấy cột thứ ba ở định dạng

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

Sau đó, bạn cần phải làm cho mảng một ma trận

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

Và bây giờ bạn có thể thực hiện các phép tính phần tử giống như bạn làm trong excel.


1
Trong khi điều này giúp tôi rất nhiều, tôi nghĩ câu trả lời có thể ngắn hơn nhiều: 1. A = np.array ([[1,2,3,4], [5,6,7,8], [9,10, 11,12]]) 2. Một mảng [:, 1] >> ([2, 6, 10])
Ufos

6

giả sử chúng ta có n X mma trận ( nhàng và mcột) nói 5 hàng và 4 cột

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

Để trích xuất các cột trong python, chúng ta có thể sử dụng danh sách hiểu như thế này

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

Bạn có thể thay thế 4 bằng bất kỳ số lượng cột nào mà ma trận của bạn có. Kết quả là

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


Điều này có tạo ra một danh sách hoàn toàn mới không?
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

Thêm một cách sử dụng ma trận

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

Nếu bạn có một mảng hai chiều trong Python (không phải numpy), bạn có thể trích xuất tất cả các cột như vậy,

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

Thực thi mã này sẽ mang lại,

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

Tất nhiên, bạn có thể trích xuất một cột theo chỉ mục (ví dụ columns[0])


2

Mặc dù sử dụng zip(*iterable)để hoán chuyển danh sách lồng nhau, bạn cũng có thể sử dụng các mục sau nếu danh sách lồng nhau có độ dài khác nhau:

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

kết quả trong:

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

Cột đầu tiên là như vậy:

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

2

Chà một chút 'muộn' ...

Trong trường hợp hiệu suất hoạt động và dữ liệu của bạn có dạng hình chữ nhật, bạn cũng có thể lưu trữ dữ liệu theo một chiều và truy cập các cột bằng cách cắt thông thường, ví dụ ...

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]

Điều gọn gàng là điều này thực sự nhanh chóng. Tuy nhiên , các chỉ số tiêu cực không hoạt động ở đây! Vì vậy, bạn không thể truy cập cột hoặc hàng cuối cùng theo chỉ số -1.

Nếu bạn cần lập chỉ mục tiêu cực, bạn có thể điều chỉnh các hàm truy cập một chút, ví dụ:

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]

Tôi đã kiểm tra phương pháp này và chi phí lấy cột là rẻ hơn so với lồng cho các vòng lặp. Tuy nhiên, việc giảm ma trận 2d xuống 1d rất tốn kém nếu ma trận lớn, giả sử 1000 * 1000.
Zhongjun 'Mark' Jin

2

Nếu bạn muốn lấy nhiều hơn chỉ một cột, chỉ cần sử dụng lát:

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

2

Tôi thích gợi ý tiếp theo: có ma trận được đặt tên matrix_avà sử dụng column_number, ví dụ:

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

Chỉ cần sử dụng transpose (), sau đó bạn có thể nhận được colummns dễ dàng như bạn nhận được hàng

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

0

Tất cả các cột từ một ma trận vào một danh sách mới:

N = len(matrix) 
column_list = [ [matrix[row][column] for row in range(N)] for column in range(N) ]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.