Chuyển một mảng NumPy


191

Tôi sử dụng Python và NumPy và có một số vấn đề với "transpose":

import numpy as np
a = np.array([5,4])
print(a)
print(a.T)

Gọi a.Tlà không hoán chuyển mảng. Nếu alà ví dụ [[],[]]thì nó chuyển đổi chính xác, nhưng tôi cần chuyển vị [...,...,...].


cũng đã thử "in a.transpose" giống như vậy nhưng không thành công, không hoán đổi ...
vào

Câu trả lời:


245

Nó hoạt động chính xác như nó được yêu cầu. Chuyển vị của mảng 1D vẫn là mảng 1D ! (Nếu bạn đã quen với MATLAB, về cơ bản, nó không có khái niệm về mảng 1D. Mảng "1D" của Matlab là 2D.)

Nếu bạn muốn biến vectơ 1D của mình thành một mảng 2D và sau đó hoán chuyển nó, chỉ cần cắt nó với np.newaxis(hoặc None, chúng giống nhau, newaxischỉ dễ đọc hơn).

import numpy as np
a = np.array([5,4])[np.newaxis]
print(a)
print(a.T)

Nói chung, mặc dù, bạn không cần phải lo lắng về điều này. Thêm kích thước phụ thường không phải là những gì bạn muốn, nếu bạn chỉ làm theo thói quen. Numpy sẽ tự động phát một mảng 1D khi thực hiện các phép tính khác nhau. Thường không cần phân biệt vectơ hàng và vectơ cột (cả hai đều không phải là vectơ . Cả hai đều là 2D!) Khi bạn chỉ muốn một vectơ.


2
@thaking - Tôi chỉ sử dụng np.arangeđể nhanh chóng tạo một mảng 1D. Nó hoạt động chính xác như nhau cho a = np.array([5,4]).
Joe Kington

2
@thaking Nếu bạn chưa quen với numpy - hãy nhớ rằng dấu ngoặc tròn ()không biểu thị một kích thước bổ sung trong numpy. Nếu a = np.arange(10)sau đó aarray([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])như được sản xuất bởi a.__repr__(). Đây là một a.ndim --> 1vectơ 1 chiều (nghĩa là ) được biểu thị bằng dấu ngoặc vuông []. Các array( ... )không được nhìn thấy khi bạn làm một trong hai print(a)hoặc a.__str__().
dtlussier

7
@JoeKington có một tình huống phát sóng mảng 1D là hữu ích. Tính khoảng cách giữa tất cả các điểm 1D trong một mảng. Nhờ giải pháp của bạn, người ta có thể thực hiện x - x [np.newaxis] .T cung cấp ma trận khoảng cách
JuanPi

4
Cá nhân, tôi thấy np.vstack()hoạt động để rõ ràng hơn : print np.vstack(a).
Alexander Pozdneev

2
Nó không chỉ là MATLAB, mà đại số tuyến tính có khái niệm về một vectơ hàng / cột. Numpy rất bình dị với những người đến từ nhiều nơi, không chỉ là MATLAB.
eric

133

Sử dụng hai cặp khung thay vì một. Điều này tạo ra một mảng 2D, có thể được hoán vị, không giống như mảng 1D bạn tạo nếu bạn sử dụng một cặp khung.

import numpy as np    
a = np.array([[5, 4]])
a.T

Ví dụ kỹ lưỡng hơn:

>>> a = [3,6,9]
>>> b = np.array(a)
>>> b.T
array([3, 6, 9])         #Here it didn't transpose because 'a' is 1 dimensional
>>> b = np.array([a])
>>> b.T
array([[3],              #Here it did transpose because a is 2 dimensional
       [6],
       [9]])

Sử dụng shapephương pháp của Numpy để xem những gì đang xảy ra ở đây:

>>> b = np.array([10,20,30])
>>> b.shape
(3,)
>>> b = np.array([[10,20,30]])
>>> b.shape
(1, 3)

11
Tôi thích giải pháp này cho [np.newaxis], nó trông imo thanh lịch hơn.
PhilMacKay

Máy móc không thông minh. Ngay cả khi bạn chỉ có một người vợ, nó nên được tuyên bố là người vợ đầu tiên của bạn.
Sreeragh AR

Đây phải là câu trả lời được chọn
bruno

79

Đối với mảng 1D :

a = np.array([1, 2, 3, 4])
a = a.reshape((-1, 1)) # <--- THIS IS IT

print a
array([[1],
       [2],
       [3],
       [4]])

Khi bạn hiểu rằng -1 ở đây có nghĩa là "càng nhiều hàng càng cần thiết", tôi thấy đây là cách dễ nhất để "hoán đổi" một mảng. Nếu mảng của bạn có chiều cao hơn chỉ cần sử dụng a.T.


5
Lưu ý rằng điều này chỉ hoạt động với các vectơ. Nếu bạn có mảng 2 chiều, các thao tác transposereshapesửa đổi mảng theo các cách khác nhau (hình dạng hình ảnh kết quả là giống nhau, nhưng các yếu tố được đặt khác nhau).
johndodo

2
Cảm ơn nhận xét của bạn. Tôi thấy quan điểm của bạn, nhưng tôi nghĩ rằng nó làm mất tập trung hơn là nó xóa câu trả lời của tôi bởi vì tôi đưa ra một giải pháp một dòng đơn giản cho câu hỏi chính xác mà @ khung hình. Đó không phải là về mảng 2-d, mà là về mảng 1-d. Táo và lê ở đây.
Ulf Aslak

2
Tất nhiên. Câu trả lời của bạn là chính xác và thanh lịch cho trường hợp này, tôi không bao giờ có ý chỉ trích nó. Nhưng với tiêu đề câu hỏi ("Chuyển một mảng NumPy") tôi nghi ngờ nhiều khách truy cập sẽ đến đây để tìm giải pháp chung chung hơn và tôi muốn cảnh báo họ rằng nó không áp dụng được cho mảng 2D. Nếu không, câu trả lời của bạn là chính xác và phù hợp với câu hỏi của OP.
johndodo

@UlfAslak, vui lòng cập nhật câu trả lời của bạn rằng cách tiếp cận của bạn không thể khái quát hóa cho mảng ND, luôn luôn tốt để làm rõ phía trước như được đề xuất bởi! & không phải là một lớp lót.!
Anu

18

Bạn có thể chuyển đổi một vectơ hiện có thành một ma trận bằng cách gói nó trong một bộ dấu ngoặc vuông bổ sung ...

from numpy import *
v=array([5,4]) ## create a numpy vector
array([v]).T ## transpose a vector into a matrix

numpy cũng có một matrixlớp (xem mảng so với ma trận ) ...

matrix(v).T ## transpose a vector into a matrix

14

mảng 1D numpy -> ma trận cột / hàng:

>>> a=np.array([1,2,4])
>>> a[:, None]    # col
array([[1],
       [2],
       [4]])
>>> a[None, :]    # row, or faster `a[None]`
array([[1, 2, 4]])

Và như @ joe-Kington nói, bạn có thể thay thế Nonebằng np.newaxischo dễ đọc.


10

Để 'hoán đổi' một mảng 1d sang cột 2d, bạn có thể sử dụng numpy.vstack:

>>> numpy.vstack(numpy.array([1,2,3]))
array([[1],
       [2],
       [3]])

Nó cũng hoạt động cho danh sách vanilla:

>>> numpy.vstack([1,2,3])
array([[1],
       [2],
       [3]])

1
@sandroscodelller, bạn đã xem mã bên dưới vstackchưa? np.concatenate([atleast_2d(_m) for _m in tup], 0). Nó chia mảng thành (1,1) mảng và nối các mảng đó lại! Trong quá trình nó tạo một bản sao, trong khi tất cả những người định hình lại tạo ra một cái nhìn.
hpaulj

3

Bạn chỉ có thể hoán chuyển một mảng 2D. Bạn có thể sử dụng numpy.matrixđể tạo một mảng 2D. Đây là ba năm muộn, nhưng tôi chỉ thêm vào các giải pháp có thể:

import numpy as np
m = np.matrix([2, 3])
m.T

Việc sử dụng np.matrixlà không cần thiết, và nói chung là không được khuyến khích.
hpaulj



2

Giải pháp khác.... :-)

import numpy as np

a = [1,2,4]

[1, 2, 4]

b = np.array([a]).T

mảng ([[1], [2], [4]])


Vấn đề với giải pháp này là gì?!
omotto

1

Tôi chỉ củng cố bài viết trên, hy vọng nó sẽ giúp người khác tiết kiệm thời gian:

Mảng dưới đây có (2, )kích thước, đó là mảng 1 chiều,

b_new = np.array([2j, 3j])  

Có hai cách để hoán chuyển mảng 1-D:


cắt nó với "np.newaxis" hoặc không.!

print(b_new[np.newaxis].T.shape)
print(b_new[None].T.shape)

cách viết khác, ở trên mà không cần Thoạt động.!

print(b_new[:, np.newaxis].shape)
print(b_new[:, None].shape)

Gói [] hoặc sử dụng np.matrix, có nghĩa là thêm một chiều mới.!

print(np.array([b_new]).T.shape)
print(np.matrix(b_new).T.shape)

0

Như một số ý kiến ​​ở trên đã đề cập, chuyển vị của mảng 1D là mảng 1D, vì vậy một cách để hoán chuyển mảng 1D sẽ là chuyển đổi mảng thành ma trận như sau:

np.transpose(a.reshape(len(a), 1))


0

Có một phương pháp không được mô tả trong các câu trả lời nhưng được mô tả trong tài liệu cho numpy.ndarray.transposephương pháp:

Đối với mảng 1-D, điều này không có tác dụng, vì một vectơ chuyển đổi chỉ đơn giản là cùng một vectơ. Để chuyển đổi mảng 1-D thành vectơ cột 2D, phải thêm kích thước bổ sung. np.atleast2d (a) .T đạt được điều này, cũng như một [:, np.newaxis].

Người ta có thể làm:

import numpy as np
a = np.array([5,4])
print(a)
print(np.atleast_2d(a).T)

Mà (imo) là đẹp hơn so với sử dụng newaxis.


0

Về cơ bản những gì hàm chuyển đổi làm là hoán đổi hình dạng và bước tiến của mảng:

>>> a = np.ones((1,2,3))

>>> a.shape
(1, 2, 3)

>>> a.T.shape
(3, 2, 1)

>>> a.strides
(48, 24, 8)

>>> a.T.strides
(8, 24, 48)

Trong trường hợp mảng numpy 1D (mảng hạng 1), hình dạng và sải chân là các bộ dữ liệu 1 phần tử và không thể hoán đổi, và chuyển vị của mảng 1D như vậy trả về nó không thay đổi. Thay vào đó, bạn có thể hoán chuyển một "vectơ hàng" (mảng hình numpy (1, n)) thành một "vectơ cột" (mảng hình numpy (n, 1)). Để đạt được điều này, trước tiên bạn phải chuyển mảng numpy 1D của mình thành vector hàng và sau đó hoán đổi hình dạng và sải chân (hoán vị nó). Dưới đây là một chức năng thực hiện nó:

from numpy.lib.stride_tricks import as_strided

def transpose(a):
    a = np.atleast_2d(a)
    return as_strided(a, shape=a.shape[::-1], strides=a.strides[::-1])

Thí dụ:

>>> a = np.arange(3)
>>> a
array([0, 1, 2])

>>> transpose(a)
array([[0],
       [1],
       [2]])

>>> a = np.arange(1, 7).reshape(2,3)
>>> a     
array([[1, 2, 3],
       [4, 5, 6]])

>>> transpose(a)
array([[1, 4],
       [2, 5],
       [3, 6]])

Tất nhiên bạn không phải làm theo cách này vì bạn có mảng 1D và bạn có thể định hình lại trực tiếp thành (n, 1)mảng bằng a.reshape((-1, 1))hoặc a[:, None]. Tôi chỉ muốn chứng minh làm thế nào hoán vị một mảng hoạt động.


0

Cách tôi đã học để thực hiện điều này một cách nhỏ gọn và dễ đọc cho các mảng 1-D, cho đến nay:

h = np.array([1,2,3,4,5])

v1 = np.vstack(h)
v2 = np.c_[h]

h1 = np.hstack(v1)
h2 = np.r_[v2[:,0]]

numpy.r_ numpy.c_ dịch các đối tượng lát thành nối tương ứng dọc theo trục thứ nhất và thứ hai, tương ứng. Do đó, việc cắt v2 [:, 0] khi hoán đổi mảng dọc v2 thành mảng ngang h2

numpy.vstack tương đương với việc ghép dọc trục thứ nhất sau khi các mảng hình 1-D (N,) đã được định hình lại thành (1, N). Tái tạo mảng chia cho vsplit .

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.