การโอนย้ายอาร์เรย์ NumPy


193

ฉันใช้ Python และ NumPy และมีปัญหาบางอย่างกับ "transpose":

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

การเรียกใช้a.Tไม่ได้ทำการเปลี่ยนอาเรย์ ถ้าaเป็นเช่น[[],[]]นั้นมัน transposes อย่างถูกต้อง แต่ฉันต้อง transpose [...,...,...]ของ


ก็ลอง "พิมพ์ a.transpose" ซึ่งเหมือนกัน แต่ไม่มีความสำเร็จไม่
ไขว้เขว

คำตอบ:


247

มันทำงานตรงตามที่ควรจะเป็น การเปลี่ยนเส้นทางของอาร์เรย์1Dยังคงเป็นอาร์เรย์1D ! (ถ้าคุณคุ้นเคยกับ matlab โดยพื้นฐานแล้วมันไม่มีแนวคิดของอาร์เรย์ 1D อาร์เรย์ "1D" ของ Matlab นั้นเป็น 2D)

หากคุณต้องการเปลี่ยนเวกเตอร์ 1D ของคุณให้เป็นอาร์เรย์ 2D แล้วแปลงมันให้ตัดมันด้วยnp.newaxis(หรือNoneพวกมันเหมือนกันnewaxisสามารถอ่านได้มากขึ้น)

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

โดยทั่วไปแล้วคุณไม่จำเป็นต้องกังวลเกี่ยวกับเรื่องนี้ การเพิ่มมิติพิเศษนั้นไม่ใช่สิ่งที่คุณต้องการหากคุณเพิ่งทำมันให้เป็นนิสัย Numpy จะออกอากาศอาเรย์ 1D โดยอัตโนมัติเมื่อทำการคำนวณที่หลากหลาย โดยทั่วไปไม่จำเป็นต้องแยกแยะระหว่างเวกเตอร์แถวและเวกเตอร์คอลัมน์ (ซึ่งไม่ใช่เวกเตอร์พวกเขาทั้งสองเป็น 2D!) เมื่อคุณต้องการเวกเตอร์


2
@thaking - ฉันเพิ่งnp.arangeสร้างอาร์เรย์ 1D อย่างรวดเร็ว a = np.array([5,4])มันทำงานเหมือนกันกับ
Joe Kington

2
@thaking หากคุณยังใหม่ต่อผู้ที่ไม่รู้จัก - โปรดจำไว้ว่าเครื่องหมายวงเล็บเหลี่ยม()ไม่ได้บ่งบอกถึงมิติเพิ่มเติมในการตัดสิน หากa = np.arange(10)แล้วaจะเป็นที่ผลิตโดยarray([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) a.__repr__()นี่คือ 1 มิติ (คือa.ndim --> 1) []เวกเตอร์ตามที่ระบุโดยวงเล็บ array( ... )ไม่เห็นเมื่อคุณทำอย่างใดอย่างหนึ่งหรือprint(a) a.__str__()
dtlussier

7
@ JoeKington มีสถานการณ์ที่การแพร่ภาพของอาร์เรย์ 1D มีประโยชน์ การคำนวณระยะทางระหว่างจุด 1D ทั้งหมดในอาร์เรย์ ด้วยวิธีแก้ปัญหาของคุณเราสามารถทำได้ x - x [np.newaxis] .T ซึ่งให้เมทริกซ์ระยะทาง
JuanPi

4
ส่วนตัวผมพบว่าการดำเนินการจะเป็นที่ชัดเจนมากขึ้น:np.vstack() print np.vstack(a)
Alexander Pozdneev

2
มันไม่ใช่แค่ matlab แต่พีชคณิตเชิงเส้นมีแนวคิดของเวกเตอร์แถว / คอลัมน์ Numpy เป็นคนที่มีนิสัยแปลก ๆ จากหลาย ๆ ที่ไม่ใช่แค่ matlab
eric

135

ใช้วงเล็บคู่สองคู่แทนหนึ่งคู่ สิ่งนี้สร้างอาร์เรย์ 2D ซึ่งสามารถย้ายได้ซึ่งแตกต่างจากอาร์เรย์ 1D ที่คุณสร้างหากคุณใช้วงเล็บคู่หนึ่งคู่

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

ตัวอย่างที่ละเอียดยิ่งขึ้น:

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

ใช้shapeวิธีของ numpy เพื่อดูว่าเกิดอะไรขึ้นที่นี่:

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

11
ฉันชอบวิธีนี้มากกว่า [np.newaxis] หนึ่งมันดูดีกว่า imo
PhilMacKay

เครื่องจักรนั้นไม่ฉลาด แม้ว่าคุณจะมีภรรยาเพียงคนเดียวก็ควรได้รับการประกาศให้เป็นภรรยาคนแรกของคุณ
Sreeragh AR

นี่ควรเป็นคำตอบที่เลือก
bruno

79

สำหรับอาร์เรย์ 1D :

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

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

เมื่อคุณเข้าใจว่า -1 ที่นี่หมายถึง "แถวมากที่สุดเท่าที่ต้องการ" ฉันพบว่านี่เป็นวิธีที่ "อ่าน" ได้ดีที่สุดในอาร์เรย์ a.Tหากอาร์เรย์ของคุณเป็นของมิติที่สูงขึ้นเพียงแค่ใช้


5
โปรดทราบว่าสิ่งนี้ใช้ได้กับเวกเตอร์เท่านั้น หากคุณมีอาเรย์สองมิติการดำเนินการtransposeและreshapeแก้ไขอาเรย์ในรูปแบบที่แตกต่างกัน (รูปร่างของภาพที่ได้จะเหมือนกัน
johndodo

2
ขอบคุณสำหรับคำพูดของคุณ ฉันเห็นประเด็นของคุณ แต่ฉันคิดว่ามันเบี่ยงเบนความสนใจมากกว่าคำตอบของฉันเพราะฉันให้คำตอบเดียวกับคำถามง่ายๆที่ @thaking frames มันไม่เกี่ยวกับอาร์เรย์ 2 มิติ แต่เป็นอาร์เรย์ 1 มิติ แอปเปิ้ลและลูกแพร์ที่นี่
Ulf Aslak

2
แน่นอน. คำตอบของคุณถูกต้องและสวยงามสำหรับกรณีนี้ฉันไม่เคยตั้งใจจะวิจารณ์เลย แต่ให้ชื่อคำถาม ("การโอนอาเรย์ของ NumPy") ฉันสงสัยว่าผู้เยี่ยมชมจำนวนมากจะมาที่นี่เพื่อหาคำตอบทั่วไปเพิ่มเติมและฉันต้องการเตือนพวกเขาว่ามันไม่สามารถใช้ได้กับอาร์เรย์ 2 มิติ มิฉะนั้นคำตอบของคุณจะถูกต้องและเหมาะสมกับคำถามของ OP
johndodo

@UlfAslak โปรดอัปเดตคำตอบของคุณว่าวิธีการของคุณไม่ได้เป็นแนวทั่วไปสำหรับ ND array มันเป็นสิ่งที่ดีเสมอที่จะได้รับคำแนะนำจาก! johndodo ดังนั้นจึงไม่มีใครควรใช้เทคนิคของคุณอย่างผิด ๆ ! ไม่ใช่สายการบิน!
Anu

18

คุณสามารถแปลงเวกเตอร์ที่มีอยู่เป็นเมทริกซ์ได้โดยการห่อในชุดวงเล็บเหลี่ยมพิเศษ ...

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

numpy ยังมีmatrixคลาส (ดูอาร์เรย์กับเมทริกซ์ ) ...

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

14

อาร์เรย์ 1D numpy -> เมทริกซ์คอลัมน์ / แถว:

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

และตามที่ @ joe-kington กล่าวไว้คุณสามารถแทนที่Noneด้วยnp.newaxisความสามารถในการอ่านได้


10

หากต้องการ 'เปลี่ยน' อาเรย์ 1d เป็นคอลัมน์ 2d คุณสามารถใช้numpy.vstack:

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

นอกจากนี้ยังใช้กับรายการวานิลลา:

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

1
@Sandroscodelller คุณดูโค้ดที่เกี่ยวข้องแล้วvstackหรือยัง? np.concatenate([atleast_2d(_m) for _m in tup], 0). มันแบ่งอาร์เรย์ออกเป็นอาร์เรย์ (1,1) และเชื่อมต่อเหล่านั้นเข้าด้วยกัน! ในกระบวนการมันทำสำเนาในขณะที่ทุกคนที่ก่อร่างใหม่ทำให้มุมมอง
hpaulj

3

คุณสามารถย้ายอาเรย์ 2D ได้เท่านั้น คุณสามารถใช้numpy.matrixเพื่อสร้างอาร์เรย์ 2D นี่เป็นเวลาสามปีที่ผ่านมา แต่ฉันแค่เพิ่มโซลูชันที่เป็นไปได้:

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

การใช้np.matrixไม่จำเป็นและมักถูกท้อแท้
hpaulj



2

ทางออกอื่น .... :-)

import numpy as np

a = [1,2,4]

[1, 2, 4]

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

อาร์เรย์ ([[1], [2], [4]])


ปัญหาในการแก้ไขปัญหานี้คืออะไร!
omotto

1

ฉันเพิ่งรวบรวมโพสต์ข้างต้นหวังว่าจะช่วยให้ผู้อื่นประหยัดเวลา:

อาร์เรย์ด้านล่างมี(2, )มิติมันเป็นอาร์เรย์ 1 มิติ

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

มีสองวิธีในการแปลงอาร์เรย์ 1-D:


เชือดมันด้วย "np.newaxis" หรือไม่มีเลย!

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

วิธีอื่น ๆ ในการเขียนข้างต้นโดยไม่มีTการดำเนินการ!

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

การตัด [] หรือใช้ np.matrix หมายถึงการเพิ่มมิติใหม่!

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

0

ดังที่ความคิดเห็นข้างต้นกล่าวถึงการโยกย้ายของ 1D arrays คือ 1D arrays ดังนั้นวิธีหนึ่งในการโยกย้าย 1D array จะเป็นการแปลง array ให้เป็น matrix ดังนี้:

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


0

มีวิธีการที่ไม่ได้อธิบายไว้ในคำตอบ แต่อธิบายไว้ในเอกสารประกอบสำหรับnumpy.ndarray.transposeวิธีการ:

สำหรับอาร์เรย์ 1-D สิ่งนี้ไม่มีผลกระทบเนื่องจากเวกเตอร์ที่ถูกเปลี่ยนเป็นเพียงเวกเตอร์เดียวกัน ในการแปลงอาร์เรย์ 1-D เป็นเวกเตอร์คอลัมน์ 2D ต้องเพิ่มมิติข้อมูลเพิ่มเติม np.atleast2d (a) .T ทำสิ่งนี้เช่นเดียวกับ [:, np.newaxis]

หนึ่งสามารถทำได้:

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

ซึ่ง (IMO) newaxisเป็นดีกว่ากว่าการใช้


0

โดยพื้นฐานแล้วฟังก์ชั่นการแปลงสัญญาณคือการสลับรูปร่างและความก้าวหน้าของอาร์เรย์:

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

ในกรณีของอาร์เรย์ 1D (อาร์เรย์อันดับ 1) รูปร่างและความก้าวหน้าเป็น 1-tuples และไม่สามารถสลับได้ แต่คุณสามารถเปลี่ยน "row-vector" (อาเรย์ของรูปร่าง(1, n)) ไปเป็น "column-vector" (อาเรย์ของรูปร่างที่มีรูปร่าง(n, 1)) เพื่อให้บรรลุสิ่งนี้คุณต้องแปลงอาร์เรย์ 1D numpy ของคุณเป็นแถวเวกเตอร์แล้วสลับรูปร่างและความก้าวหน้า (แปลงเป็น) ด้านล่างเป็นฟังก์ชั่นที่ทำ:

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

ตัวอย่าง:

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

แน่นอนคุณจะได้ไม่ต้องทำวิธีนี้เนื่องจากคุณมีอาร์เรย์ 1D และคุณโดยตรงสามารถก่อร่างใหม่ลงใน(n, 1)อาร์เรย์โดยหรือa.reshape((-1, 1)) a[:, None]ฉันแค่ต้องการแสดงให้เห็นว่าการแปลงอาเรย์เป็นอย่างไร


0

วิธีที่ฉันเรียนรู้ที่จะใช้สิ่งนี้ในขนาดกะทัดรัดและอ่านได้สำหรับอาร์เรย์ 1-D จนถึงตอนนี้:

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_แปลวัตถุชิ้นเป็น concatenation ตามแกนแรกและแกนที่สองตามลำดับ ดังนั้นการแบ่ง v2 [:, 0] ในการย้ายอาเรย์แนวดิ่ง v2 กลับสู่อาเรย์แนวนอน h2

numpy.vstackเทียบเท่ากับการต่อข้อมูลตามแกนแรกหลังจาก 1-D อาร์เรย์ของรูปร่าง (N,) ได้ถูกเปลี่ยนเป็น (1, N) อาร์เรย์ฟื้นฟูหารด้วยvsplit

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.