2009-02-20 41 views
177

Tôi không thể tìm ra cách sử dụng mảng hoặc ma trận theo cách mà tôi thường sử dụng danh sách. Tôi muốn tạo một mảng trống (hoặc ma trận) và sau đó thêm một cột (hoặc hàng) vào nó tại một thời điểm.Làm cách nào để tạo một mảng/ma trận trống trong NumPy?

Tại thời điểm này cách duy nhất tôi có thể tìm thấy để làm điều này là như sau:

mat = None 
for col in columns: 
    if mat is None: 
     mat = col 
    else: 
     mat = hstack((mat, col)) 

Trong khi đó nếu nó là một danh sách, tôi muốn làm một cái gì đó như thế này:

list = [] 
for item in data: 
    list.append(item) 

Có cách sử dụng loại ký hiệu đó cho NumPy mảng hoặc ma trận?

Trả lời

261

Bạn có mô hình tinh thần sai khi sử dụng NumPy hiệu quả. Các mảng NumPy được lưu trữ trong các khối liên tiếp của bộ nhớ. Nếu bạn muốn thêm hàng hoặc cột vào một mảng hiện có, toàn bộ mảng cần phải được sao chép vào một khối bộ nhớ mới, tạo ra các khoảng trống cho các phần tử mới được lưu trữ. Điều này là rất kém hiệu quả nếu được thực hiện nhiều lần để xây dựng một mảng.

Trong trường hợp thêm hàng, đặt cược tốt nhất của bạn là tạo ra một mảng đó là lớn như bộ dữ liệu của bạn cuối cùng sẽ được, và sau đó thêm dữ liệu vào nó chèo-by-hàng:

>>> import numpy 
>>> a = numpy.zeros(shape=(5,2)) 
>>> a 
array([[ 0., 0.], 
    [ 0., 0.], 
    [ 0., 0.], 
    [ 0., 0.], 
    [ 0., 0.]]) 
>>> a[0] = [1,2] 
>>> a[1] = [2,3] 
>>> a 
array([[ 1., 2.], 
    [ 2., 3.], 
    [ 0., 0.], 
    [ 0., 0.], 
    [ 0., 0.]]) 
+75

Ngoài ra còn có numpy.empty() nếu bạn không cần 0 mảng. – janneb

+10

Lợi ích của việc sử dụng rỗng() trên số không() là gì? – Zach

+25

rằng nếu bạn sẽ khởi tạo nó với dữ liệu của bạn ngay lập tức, bạn tiết kiệm chi phí của zeroing nó. – marcorossi

6

Bạn có thể sử dụng chức năng nối thêm. Đối với hàng:

>>> from numpy import * 
>>> a = array([10,20,30]) 
>>> append(a, [[1,2,3]], axis=0) 
array([[10, 20, 30],  
     [1, 2, 3]]) 

cho cột:

>>> append(a, [[15],[15]], axis=1) 
array([[10, 20, 30, 15],  
     [1, 2, 3, 15]]) 

EDIT
Tất nhiên, như đã đề cập trong câu trả lời khác, trừ khi bạn đang thực hiện một số chế biến (ví dụ đảo ngược.) Trên ma trận/mảng MỌI thời gian bạn thêm một cái gì đó vào nó, tôi sẽ chỉ tạo một danh sách, thêm vào nó sau đó chuyển đổi nó thành một mảng.

62

Mảng NumPy là một cấu trúc dữ liệu rất khác với danh sách và được thiết kế để sử dụng theo nhiều cách khác nhau. Việc bạn sử dụng hstack có khả năng rất không hiệu quả ... mỗi lần bạn gọi nó, tất cả dữ liệu trong mảng hiện có được sao chép vào một mảng mới. (Nếu chức năng append có cùng một vấn đề.) Nếu bạn muốn xây dựng ma trận một cột tại một thời điểm, bạn có thể là tốt nhất để giữ nó trong danh sách cho đến khi nó kết thúc, và chỉ sau đó chuyển nó thành một mảng.

ví dụ:


mylist = [] 
for item in data: 
    mylist.append(item) 
mat = numpy.array(mylist) 

item có thể là một danh sách, một mảng hoặc bất kỳ iterable, miễn vì mỗi item có cùng một số yếu tố.
Trong trường hợp đặc biệt này (data là một số iterable giữ các cột ma trận), bạn chỉ có thể sử dụng


mat = numpy.array(data) 

(Cũng lưu ý rằng việc sử dụng list như một tên biến có lẽ là thói quen không tốt vì nó mặt nạ được xây dựng trong loại bằng tên đó, có thể dẫn đến lỗi.)

EDIT:

Nếu vì một lý do nào bạn thực sự muốn tạo một mảng trống rỗng, bạn chỉ có thể sử dụng numpy.array([]), nhưng điều này hiếm khi hữu ích!

+1

Các mảng/ma trận có vón cục khác với Matlab? – levesque

+2

@levesque Nhìn [HERE] (http://www.scipy.org/NumPy_for_Matlab_Users) – pmav99

+0

Nếu vì lý do nào đó bạn cần xác định một mảng trống, nhưng với độ rộng cố định (ví dụ: 'np.concatenate()'), bạn có thể sử dụng: 'np.empty ((0, some_width))'. 0, vì vậy mảng đầu tiên của bạn sẽ không bị rác. – NumesSanguis

3

Nếu bạn hoàn toàn không biết kích thước cuối cùng của mảng, bạn có thể tăng kích thước của mảng như thế này:

my_arr = numpy.zeros((0,5)) 
for i in range(3): 
    my_arr=numpy.concatenate((my_arr, numpy.ones((1,5)))) 
print(my_arr) 

[[ 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1.]] 
  • Thông báo các 0 trong dòng đầu tiên.
  • numpy.append là một tùy chọn khác. Nó gọi numpy.concatenate.
18

Tôi đã xem xét điều này rất nhiều vì tôi cần sử dụng numpy.array như một bộ trong một trong các dự án trường học của mình và tôi cần khởi tạo trống ... Tôi không tìm thấy câu trả lời nào có liên quan ở đây Stack Overflow, vì vậy tôi bắt đầu vẽ một cái gì đó.

# Initialize your variable as an empty list first 
In [32]: x=[] 
# and now cast it as a numpy ndarray 
In [33]: x=np.array(x) 

Kết quả sẽ là:

In [34]: x 
Out[34]: array([], dtype=float64) 

Vì vậy, bạn có thể trực tiếp khởi tạo một mảng np như sau:

In [36]: x= np.array([], dtype=np.float64) 

Tôi hy vọng điều này sẽ giúp.

+0

Điều này không hoạt động đối với mảng, như trong câu hỏi, nhưng nó có thể hữu ích cho vectơ. – divenex

28

Để tạo mảng đa chiều trống trong NumPy (ví dụ: mảng 2D m*n để lưu ma trận), trong trường hợp bạn không biết m số hàng bạn sẽ thêm và không quan tâm đến chi phí tính toán mà Stephen Simmons đã đề cập (cụ thể là xây dựng lại mảng tại mỗi phụ lục), bạn có thể ép đến 0 thứ nguyên mà bạn muốn nối thêm vào: X = np.empty(shape=[0, n]).

Bằng cách này bạn có thể sử dụng ví dụ (ở đây m = 5 mà chúng tôi cho rằng chúng tôi không biết khi tạo ma trận rỗng, và n = 2):

import numpy as np 

n = 2 
X = np.empty(shape=[0, n]) 

for i in range(5): 
    for j in range(2): 
     X = np.append(X, [[i, j]], axis=0) 

print X 

mà sẽ cung cấp cho bạn:

[[ 0. 0.] 
[ 0. 1.] 
[ 1. 0.] 
[ 1. 1.] 
[ 2. 0.] 
[ 2. 1.] 
[ 3. 0.] 
[ 3. 1.] 
[ 4. 0.] 
[ 4. 1.]] 
2

Bạn có thể áp dụng nó để tạo bất kỳ loại mảng nào, như số không:

a = range(5) 
a = [i*0 for i in a] 
print a 
[0, 0, 0, 0, 0] 
+2

Nếu bạn muốn làm điều đó trong python tinh khiết, 'a = [0] * 5' là giải pháp đơn giản –

0

De đang chờ xử lý những gì bạn đang sử dụng cho, bạn có thể cần phải xác định kiểu dữ liệu (xem 'dtype').

Ví dụ, để tạo ra một mảng 2D của các giá trị 8-bit (phù hợp để sử dụng như một hình ảnh đơn sắc):

myarray = numpy.empty(shape=(H,W),dtype='u1') 

Đối với một hình ảnh RGB, bao gồm số lượng các kênh màu trong hình dạng: shape=(H,W,3)

Bạn cũng có thể muốn xem xét không khởi tạo với numpy.zeros thay vì sử dụng numpy.empty. Xem ghi chú here.

Các vấn đề liên quan