Numpy - เพิ่มแถวในอาร์เรย์


161

หนึ่งจะเพิ่มแถวในอาร์เรย์ numpy ได้อย่างไร

ฉันมีอาร์เรย์ A:

A = array([[0, 1, 2], [0, 2, 0]])

ฉันต้องการเพิ่มแถวไปยังอาร์เรย์นี้จากอาร์เรย์ X อื่นหากองค์ประกอบแรกของแต่ละแถวใน X ตรงตามเงื่อนไขที่ระบุ

อาร์เรย์ Numpy ไม่มีเมธอด 'ผนวก' เหมือนกับของรายการหรืออย่างนั้น

ถ้า A และ X เป็นรายการฉันจะทำ:

for i in X:
    if i[0] < 3:
        A.append(i)

มีวิธีnumpythonicที่จะทำเทียบเท่า?

ขอบคุณ S ;-)


คำตอบ:


120

คือXอะไร ถ้าเป็นอาร์เรย์ 2 มิติคุณจะเปรียบเทียบแถวของมันกับตัวเลขได้i < 3อย่างไร:

แก้ไขหลังจากความคิดเห็นของ OP:

A = array([[0, 1, 2], [0, 2, 0]])
X = array([[0, 1, 2], [1, 2, 0], [2, 1, 2], [3, 2, 0]])

เพิ่มในAแถวทั้งหมดจากXที่องค์ประกอบแรก< 3:

import numpy as np
A = np.vstack((A, X[X[:,0] < 3]))

# returns: 
array([[0, 1, 2],
       [0, 2, 0],
       [0, 1, 2],
       [1, 2, 0],
       [2, 1, 2]])

1
ขออภัยจุดดี! สมมติว่าอาร์เรย์ 2 มิติซึ่งองค์ประกอบแรกของแต่ละแถวต้องเป็นไปตามเงื่อนไข ฉันจะแก้ไขมัน ขอบคุณ S ;-)
Darren J. Fitzpatrick

2
@ DarrenJ.Fitzpatrick เก็บไว้ในใจว่าการทำประเภทของการจัดการนี้คุณทำงานกับการทำงานที่ดี Numpy Aไม่ในก่อนการจัดสรรหน่วยความจำสำหรับอาร์เรย์ที่คุณมีอยู่ เห็นได้ชัดสำหรับปัญหาเล็ก ๆ เช่นในคำตอบนี้ไม่เป็นปัญหา แต่มันอาจเป็นปัญหาสำหรับข้อมูลขนาดใหญ่
dtlussier

166

ดีคุณสามารถทำสิ่งนี้:

  newrow = [1,2,3]
  A = numpy.vstack([A, newrow])

2
@Kris ทำไมเลิกใช้แล้ว ฉันไม่เห็นอะไรเลยในเอกสาร
Georgy

1
@Georgy พูดตามตรงฉันไม่รู้ ฉันอยู่ที่นี่เพื่อค้นหาคำตอบเช่นเดียวกับคุณ :-) ฉันจำไม่ได้แล้วว่าทำไมฉันถึงเขียนความคิดเห็นด้านบน ฉันต้องเห็นในเอกสารที่เลิกใช้แล้ว แต่ดูเอกสารตอนนี้ ... มันไม่ได้พูดอย่างนั้น เป็นไปได้ไหมที่พวกเขาเลิกใช้แล้วเปลี่ยนใจอีกครั้งและตัดสินใจว่ามันน่ารำคาญเกินกว่าที่คนจำนวนมากเกินไปจะเลิกและลบมันได้หรือไม่
Kris

32

เมื่อคำถามนี้เกิดขึ้นเมื่อ 7 ปีก่อนในเวอร์ชั่นล่าสุดที่ฉันใช้คือรุ่น numpy 1.13 และ python3 ฉันกำลังทำสิ่งเดียวกันโดยเพิ่มแถวไปยังเมทริกซ์อย่าลืมใส่วงเล็บคู่ลงในอาร์กิวเมนต์ที่สอง มิฉะนั้นจะทำให้เกิดข้อผิดพลาดด้านมิติ

ที่นี่ฉันเพิ่มในเมทริกซ์ A

1 2 3
4 5 6

กับแถว

7 8 9

การใช้งานเดียวกันใน np.r_

A= [[1, 2, 3], [4, 5, 6]]
np.append(A, [[7, 8, 9]], axis=0)

    >> array([[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9]])
#or 
np.r_[A,[[7,8,9]]]

เพียงเพื่อ intersted ของใครบางคนถ้าคุณต้องการที่จะเพิ่มคอลัมน์

array = np.c_[A,np.zeros(#A's row size)]

ติดตามสิ่งที่เราทำก่อนหน้านี้ในเมทริกซ์ A โดยเพิ่มคอลัมน์เข้าไป

np.c_[A, [2,8]]

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

11

หากไม่จำเป็นต้องคำนวณหลังจากทุกแถวมันจะเร็วกว่ามากในการเพิ่มแถวในไพ ธ อนจากนั้นแปลงเป็นจำนวนเต็ม นี่คือการทดสอบเวลาโดยใช้ python 3.6 กับ numpy 1.14 เพิ่ม 100 แถวทีละครั้ง:

import numpy as np 
from time import perf_counter, sleep

def time_it():
    # Compare performance of two methods for adding rows to numpy array
    py_array = [[0, 1, 2], [0, 2, 0]]
    py_row = [4, 5, 6]
    numpy_array = np.array(py_array)
    numpy_row = np.array([4,5,6])
    n_loops = 100

    start_clock = perf_counter()
    for count in range(0, n_loops):
       numpy_array = np.vstack([numpy_array, numpy_row]) # 5.8 micros
    duration = perf_counter() - start_clock
    print('numpy 1.14 takes {:.3f} micros per row'.format(duration * 1e6 / n_loops))

    start_clock = perf_counter()
    for count in range(0, n_loops):
        py_array.append(py_row) # .15 micros
    numpy_array = np.array(py_array) # 43.9 micros       
    duration = perf_counter() - start_clock
    print('python 3.6 takes {:.3f} micros per row'.format(duration * 1e6 / n_loops))
    sleep(15)

#time_it() prints:

numpy 1.14 takes 5.971 micros per row
python 3.6 takes 0.694 micros per row

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


10

คุณยังสามารถทำสิ่งนี้:

newrow = [1,2,3]
A = numpy.concatenate((A,newrow))

2
อืมม เมื่อฉันลองสิ่งนี้มันเพิ่งจะถูกเพิ่มไปยังจุดสิ้นสุดของ A แทนที่จะเพิ่มแถวใหม่ตามที่ OP ร้องขอ
ทอดด์แกง

13
อาจnp.concatenate((A,newrow), axis=0)
Konstantinos Roditakis

3
ขณะที่รุ่น numpy 1.12.1(และในหลาม 3) ValueError: all the input arrays must have same number of dimensionsดูเหมือนว่าพยายามที่จะเชื่อมเวกเตอร์ไปยังยกเมทริกซ์ ดูเหมือนว่ามันต้องการให้เวกเตอร์ได้รับการเปลี่ยนรูปร่างอย่างชัดเจนเป็นเวกเตอร์คอลัมน์หรือแถวก่อนที่จะพร้อมที่จะต่อกัน
MRule

3
@MRule คุณสามารถแก้ไขว่าด้วยการใช้วงเล็บสองครั้งตามคำตอบจาก @Flora PJ หลี่stackoverflow.com/a/47845065/1410035 newrow = [[1,2,3]]
Tom Saleeba


3

หากคุณสามารถดำเนินการก่อสร้างในการดำเนินการเพียงครั้งเดียวบางสิ่งเช่นคำตอบ vstack-with-fancy-indexing เป็นวิธีการที่ดี แต่ถ้าสภาพของคุณซับซ้อนมากขึ้นหรือแถวของคุณเข้ามาในทันทีคุณอาจต้องการเพิ่มจำนวนอาเรย์ ในความเป็นจริงวิธี numpythonic ที่จะทำสิ่งนี้ - แบบไดนามิกที่เติบโตอาร์เรย์ - คือการเติบโตแบบไดนามิกรายการ:

A = np.array([[1,2,3],[4,5,6]])
Alist = [r for r in A]
for i in range(100):
    newrow = np.arange(3)+i
    if i%5:
        Alist.append(newrow)
A = np.array(Alist)
del Alist

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


3

ฉันใช้ 'np.vstack' ซึ่งเร็วกว่า EX:

import numpy as np

input_array=np.array([1,2,3])
new_row= np.array([4,5,6])

new_array=np.vstack([input_array, new_row])

2

คุณสามารถใช้numpy.append()เพื่อผนวกแถวไปยังอาร์เรย์ numpty และปรับรูปร่างให้เป็นเมทริกซ์ในภายหลัง

import numpy as np
a = np.array([1,2])
a = np.append(a, [3,4])
print a
# [1,2,3,4]
# in your example
A = [1,2]
for row in X:
    A = np.append(A, row)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.