เริ่มต้นอาร์เรย์ numpy


130

มีวิธีเริ่มต้นอาร์เรย์ที่เป็นตัวเลขและเพิ่มเข้าไปหรือไม่? ฉันจะอธิบายสิ่งที่ฉันต้องการพร้อมตัวอย่างรายการ ถ้าฉันต้องการสร้างรายการของวัตถุที่สร้างในลูปฉันสามารถทำได้:

a = []
for i in range(5):
    a.append(i)

ฉันต้องการทำสิ่งที่คล้ายกันกับอาร์เรย์จำนวนนับ ฉันรู้เกี่ยวกับ vstack, เชื่อมต่อ ฯลฯ อย่างไรก็ตามดูเหมือนว่าสิ่งเหล่านี้ต้องการอาร์เรย์ numpy สองตัวเป็นอินพุต สิ่งที่ฉันต้องการคือ:

big_array # Initially empty. This is where I don't know what to specify
for i in range(5):
    array i of shape = (2,4) created.
    add to big_array

ควรจะมีรูปร่างbig_array (10,4)ต้องทำอย่างไร?


แก้ไข:

ฉันต้องการเพิ่มคำชี้แจงต่อไปนี้ ฉันรู้ว่าฉันสามารถกำหนดbig_array = numpy.zeros((10,4))และเติมเต็มได้ อย่างไรก็ตามสิ่งนี้จำเป็นต้องระบุขนาดของ big_array ล่วงหน้า ฉันรู้ขนาดในกรณีนี้ แต่ถ้าฉันไม่ทำล่ะ? เมื่อเราใช้.appendฟังก์ชันเพื่อขยายรายการใน python เราไม่จำเป็นต้องรู้ขนาดสุดท้ายล่วงหน้า ฉันสงสัยว่ามีบางอย่างที่คล้ายกันสำหรับการสร้างอาร์เรย์ที่ใหญ่กว่าจากอาร์เรย์ขนาดเล็กโดยเริ่มต้นด้วยอาร์เรย์ว่างเปล่า


[i for i in range(5)]อนึ่งตัวอย่างรหัสแรกของคุณสามารถเขียนได้อย่างเรียบร้อยและชัดถ้อยชัดคำเป็นความเข้าใจของรายการ: (เทียบเท่า: list(range(5))แม้ว่านี่จะเป็นตัวอย่างที่สร้างขึ้น)
Katriel

โซลูชันใดที่เหมาะกับคุณ ฉันกำลังพยายามทำสิ่งที่คล้ายกันเช่นx = numpy.array()เดียวกับวิธีที่เราทำในรายการเช่นy = []; แต่มันใช้ไม่ได้
kRazzy R

คำตอบ:


160

numpy.zeros

ส่งคืนอาร์เรย์ใหม่ของรูปร่างและประเภทที่กำหนดซึ่งเต็มไปด้วยศูนย์

หรือ

numpy.ones

ส่งคืนอาร์เรย์ใหม่ของรูปร่างและประเภทที่กำหนด

หรือ

numpy.empty

ส่งคืนอาร์เรย์ใหม่ของรูปร่างและประเภทที่กำหนดโดยไม่ต้องเตรียมข้อมูลเบื้องต้น


อย่างไรก็ตามความคิดที่เราสร้างอาร์เรย์โดยการต่อท้ายองค์ประกอบเข้ากับรายการนั้นไม่ได้ถูกนำมาใช้มากนักเนื่องจากมีประสิทธิภาพน้อยกว่า (ประเภทข้อมูล numpy จะอยู่ใกล้กับอาร์เรย์ C ที่อยู่ข้างใต้มาก) แต่คุณควรจัดสรรอาร์เรย์ล่วงหน้าให้มีขนาดที่คุณต้องการจากนั้นกรอกข้อมูลในแถว คุณสามารถใช้ได้numpy.appendถ้าคุณต้องการ


2
ฉันรู้ว่าฉันสามารถตั้งค่า big_array = numpy.zeros แล้วเติมด้วยอาร์เรย์ขนาดเล็กที่สร้างขึ้น อย่างไรก็ตามสิ่งนี้ทำให้ฉันต้องระบุขนาดของ big_array ล่วงหน้า ไม่มีอะไรเหมือน. ผนวกฟังก์ชั่นรายการโดยที่ฉันไม่ได้ระบุขนาดไว้ล่วงหน้า ขอบคุณ!
Curious2learn

2
@ Curious2learn ไม่ไม่มีอะไรที่เหมือนกับผนวกใน Numpy มีฟังก์ชันที่ต่ออาร์เรย์หรือเรียงซ้อนกันโดยการสร้างอาร์เรย์ใหม่ แต่ไม่สามารถทำได้โดยการต่อท้าย นี่เป็นเพราะวิธีการตั้งค่าโครงสร้างข้อมูล อาร์เรย์ Numpy ถูกทำให้รวดเร็วโดยอาศัยความสามารถในการจัดเก็บค่าที่กระชับมากขึ้น แต่จำเป็นต้องมีขนาดคงที่เพื่อให้ได้ความเร็วนี้ รายการ Python ได้รับการออกแบบให้มีความยืดหยุ่นมากขึ้นในราคาที่รวดเร็วและขนาด
Justin Peel

3
@ อยากรู้อยากเห็น: ดีมีappendในจำนวน เพียงแค่มีประสิทธิภาพน้อยกว่าที่จะไม่จัดสรรล่วงหน้า (ในกรณีนี้มีประสิทธิภาพน้อยกว่ามากเนื่องจากการappendคัดลอกอาร์เรย์ทั้งหมดในแต่ละครั้ง) ดังนั้นจึงไม่ใช่เทคนิคมาตรฐาน
Katriel

1
จะเกิดอะไรขึ้นถ้าเพียงบางส่วนของnp.emptyอาร์เรย์เต็มไปด้วยค่า? แล้วรายการ "ว่าง" ที่เหลือล่ะ?
Lee

1
ถ้าคุณรู้ว่าเพียงรู้ความกว้าง (เช่นที่จำเป็นสำหรับการnp.concatenate()), np.empty((0, some_width))คุณสามารถเริ่มต้นด้วย: 0 ดังนั้นอาร์เรย์แรกของคุณจะไม่เป็นขยะ
NumesSanguis

40

วิธีที่ฉันมักจะทำคือการสร้างรายการปกติจากนั้นผนวกข้อมูลของฉันเข้าไปในนั้นและในที่สุดก็เปลี่ยนรายการเป็นอาร์เรย์ตัวเลขดังนี้:

import numpy as np
big_array = [] #  empty regular list
for i in range(5):
    arr = i*np.ones((2,4)) # for instance
    big_array.append(arr)
big_np_array = np.array(big_array)  # transformed to a numpy array

แน่นอนว่าออบเจ็กต์สุดท้ายของคุณใช้พื้นที่สองเท่าในหน่วยความจำในขั้นตอนการสร้าง แต่การต่อท้ายรายการไพ ธ อนนั้นเร็วมากและการสร้างโดยใช้ np.array () ด้วย


11
นี่ไม่ใช่วิธีที่จะไปหากคุณรู้ขนาดของอาร์เรย์ล่วงหน้าอย่างไรก็ตาม ... ฉันใช้วิธีนี้บ่อยครั้งเมื่อฉันไม่รู้ว่าอาร์เรย์จะใหญ่แค่ไหน ตัวอย่างเช่นเมื่ออ่านข้อมูลจากไฟล์หรือกระบวนการอื่น มันไม่ได้แย่มากเท่าที่ควรในตอนแรกเนื่องจาก python และ numpy ค่อนข้างฉลาด
travc

18

แนะนำใน numpy 1.8:

numpy.full

ส่งคืนอาร์เรย์ใหม่ของรูปร่างและประเภทที่กำหนดซึ่งเต็มไปด้วย fill_value

ตัวอย่าง:

>>> import numpy as np
>>> np.full((2, 2), np.inf)
array([[ inf,  inf],
       [ inf,  inf]])
>>> np.full((2, 2), 10)
array([[10, 10],
       [10, 10]])

13

อาร์เรย์อะนาล็อกสำหรับ python's

a = []
for i in range(5):
    a.append(i)

คือ:

import numpy as np

a = np.empty((0))
for i in range(5):
    a = np.append(a, i)

5
@NicholasTJ: empty((0))เริ่มต้นอาร์เรย์ numpy
Adobe

2
วงเล็บใน np.empty ((0)) ซ้ำซ้อน
Szymon Roziewski

7

numpy.fromiter() คือสิ่งที่คุณกำลังมองหา:

big_array = numpy.fromiter(xrange(5), dtype="int")

นอกจากนี้ยังทำงานร่วมกับนิพจน์เครื่องกำเนิดไฟฟ้าเช่น:

big_array = numpy.fromiter( (i*(i+1)/2 for i in xrange(5)), dtype="int" )

หากคุณทราบความยาวของอาร์เรย์ล่วงหน้าคุณสามารถระบุได้ด้วยอาร์กิวเมนต์ "count" ซึ่งเป็นทางเลือก


2
ฉันวิ่ง timeit จริงๆและฉันคิดว่า np.fromiter () อาจจะช้ากว่า np.array () timeit ("np.array (i for i in xrange (100))", setup = "import numpy as np", number = 10000) -> 0.02539992332458496, กับ timeit ("np.fromiter ((i สำหรับ i ใน xrange ( 100)), dtype = int) ", setup =" import numpy as np ", number = 10000) -> 0.13351011276245117
hlin117

6

คุณต้องการหลีกเลี่ยงการวนซ้ำอย่างชัดเจนให้มากที่สุดเท่าที่จะเป็นไปได้เมื่อทำการคำนวณอาร์เรย์เนื่องจากจะช่วยลดความเร็วที่ได้รับจากการคำนวณรูปแบบนั้น มีหลายวิธีในการเริ่มต้นอาร์เรย์จำนวนนับ หากคุณต้องการให้มันเต็มไปด้วยศูนย์ให้ทำตามที่ katrielalex กล่าวว่า:

big_array = numpy.zeros((10,4))

แก้ไข: คุณกำลังสร้างลำดับแบบไหน? คุณควรตรวจสอบการทำงานที่แตกต่างกันที่ numpy สร้างอาร์เรย์เช่นnumpy.linspace(start, stop, size)(จำนวนระยะห่างเท่า ๆ กัน) numpy.arange(start, stop, inc)หรือ ในกรณีที่เป็นไปได้ฟังก์ชันเหล่านี้จะทำให้อาร์เรย์เร็วกว่าการทำงานเดียวกันในลูปอย่างชัดเจน


6

ในการเริ่มต้นอาร์เรย์ numpy ด้วยเมทริกซ์เฉพาะ:

import numpy as np

mat = np.array([[1, 1, 0, 0, 0],
                [0, 1, 0, 0, 1],
                [1, 0, 0, 1, 1],
                [0, 0, 0, 0, 0],
                [1, 0, 1, 0, 1]])

print mat.shape
print mat

เอาท์พุท:

(5, 5)
[[1 1 0 0 0]
 [0 1 0 0 1]
 [1 0 0 1 1]
 [0 0 0 0 0]
 [1 0 1 0 1]]

5

สำหรับตัวอย่างอาร์เรย์แรกของคุณให้ใช้

a = numpy.arange(5)

ในการเริ่มต้น big_array ให้ใช้

big_array = numpy.zeros((10,4))

นี้จะถือว่าคุณต้องการที่จะเริ่มต้นด้วยศูนย์ซึ่งเป็นปกติสวย แต่มีอื่น ๆ อีกมากมายวิธีการที่จะเริ่มต้นในอาร์เรย์ numpy

แก้ไข: หากคุณไม่ทราบขนาดของ big_array ล่วงหน้าโดยทั่วไปดีที่สุดในการสร้างครั้งแรกรายการหลามใช้ผนวกและเมื่อคุณมีทุกอย่างที่เก็บรวบรวมได้ในรายการแปลงรายการนี้เพื่ออาร์เรย์ numpy numpy.array(mylist)ใช้ เหตุผลก็คือรายการมีขึ้นเพื่อให้เติบโตอย่างมีประสิทธิภาพและรวดเร็วในขณะที่ numpy.concatenate จะไม่มีประสิทธิภาพมากเนื่องจากอาร์เรย์จำนวนนับไม่ได้เปลี่ยนขนาดได้ง่าย แต่เมื่อทุกอย่างถูกรวบรวมในรายการและคุณทราบขนาดอาร์เรย์ขั้นสุดท้ายแล้วก็สามารถสร้างอาร์เรย์จำนวนนับได้อย่างมีประสิทธิภาพ


3

ฉันขอแนะนำให้กำหนดรูปร่างก่อน จากนั้นทำซ้ำเพื่อแทรกค่า

big_array= np.zeros(shape = ( 6, 2 ))
for it in range(6):
    big_array[it] = (it,it) # For example

>>>big_array

array([[ 0.,  0.],
       [ 1.,  1.],
       [ 2.,  2.],
       [ 3.,  3.],
       [ 4.,  4.],
       [ 5.,  5.]])

3

เมื่อใดก็ตามที่คุณอยู่ในสถานการณ์ต่อไปนี้:

a = []
for i in range(5):
    a.append(i)

และคุณต้องการบางสิ่งที่คล้ายกันเป็นตัวเลขคำตอบก่อนหน้านี้หลายคำได้ชี้ให้เห็นถึงวิธีการทำ แต่เนื่องจาก @katrielalex ชี้ให้เห็นว่าวิธีการเหล่านี้ไม่ได้ผล วิธีที่มีประสิทธิภาพในการทำเช่นนี้คือการสร้างรายการยาว ๆ จากนั้นปรับรูปร่างใหม่ตามที่คุณต้องการหลังจากที่คุณมีรายการยาว ๆ ตัวอย่างเช่นสมมติว่าฉันกำลังอ่านบางบรรทัดจากไฟล์และแต่ละแถวมีรายการตัวเลขและฉันต้องการสร้างอาร์เรย์ที่เป็นตัวเลข (จำนวนบรรทัดที่อ่านความยาวของเวกเตอร์ในแต่ละแถว) นี่คือวิธีที่ฉันจะทำได้อย่างมีประสิทธิภาพมากขึ้น:

long_list = []
counter = 0
with open('filename', 'r') as f:
    for row in f:
        row_list = row.split()
        long_list.extend(row_list)
        counter++
#  now we have a long list and we are ready to reshape
result = np.array(long_list).reshape(counter, len(row_list)) #  desired numpy array

2

ฉันรู้ว่านี่ช้าไปหน่อย แต่ฉันไม่สังเกตเห็นคำตอบอื่นใดที่กล่าวถึงการจัดทำดัชนีในอาร์เรย์ว่าง:

big_array = numpy.empty(10, 4)
for i in range(5):
    array_i = numpy.random.random(2, 4)
    big_array[2 * i:2 * (i + 1), :] = array_i

ด้วยวิธีนี้คุณจะจัดสรรอาร์เรย์ผลลัพธ์ทั้งหมดล่วงหน้าด้วย numpy.emptyและกรอกข้อมูลในแถวขณะที่คุณดำเนินการโดยใช้การกำหนดดัชนี

ปลอดภัยอย่างสมบูรณ์ที่จะจัดสรรล่วงหน้าemptyแทนzerosในตัวอย่างที่คุณให้ไว้เนื่องจากคุณรับประกันว่าอาร์เรย์ทั้งหมดจะเต็มไปด้วยชิ้นส่วนที่คุณสร้างขึ้น


2

บางทีของแบบนี้จะเข้ากับความต้องการของคุณ ..

import numpy as np

N = 5
res = []

for i in range(N):
    res.append(np.cumsum(np.ones(shape=(2,4))))

res = np.array(res).reshape((10, 4))
print(res)

ซึ่งสร้างผลลัพธ์ต่อไปนี้

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