2013-06-06 59 views
22

Trong NumPy, tôi có thể nhận được kích thước (tính theo byte) của một kiểu dữ liệu cụ thể bằng cách:Kích thước của kiểu dữ liệu sử dụng NumPy

datatype(...).itemsize 

hay:

datatype(...).nbytes 

Ví dụ:

np.float32(5).itemsize #4 
np.float32(5).nbytes #4 

Tôi có hai câu hỏi. Đầu tiên, có cách nào để lấy thông tin này mà không cần tạo một cá thể của kiểu dữ liệu không? Thứ hai, sự khác biệt giữa itemsizenbytes là gì?

Trả lời

31

Bạn cần một phiên bản của dtype để nhận các mục, nhưng bạn không cần một phiên bản của ndarray. (Như sẽ trở nên rõ ràng trong một giây, nbytes là thuộc tính của mảng đó, không phải là loại dtype.)

Ví dụ:

print np.dtype(float).itemsize 
print np.dtype(np.float32).itemsize 
print np.dtype('|S10').itemsize 

Theo như sự khác biệt giữa itemsizenbytes, nbytes chỉ x.itemsize * x.size là.

Ví dụ:

In [16]: print np.arange(100).itemsize 
8 

In [17]: print np.arange(100).nbytes 
800 
+1

Câu trả lời hay. Trong thực tế, tôi không sử dụng một mảng tại thời điểm này. Trong trường hợp sử dụng thực của tôi, tôi có định dạng datafile dựa trên bản ghi - Nó có tiêu đề với 240 byte và sau đó là dữ liệu. Kích thước của dữ liệu được xác định bởi số lượng các phần tử (được đọc từ phần đầu) nhưng kiểu dữ liệu không được lưu trữ :-(Cuối cùng, tôi muốn người dùng có thể vượt qua 'dtype = ... 'và từ kiểu dữ liệu đó, tôi lấy sizeof của mỗi phần tử dữ liệu và vì vậy tôi có thể biết kích thước của dữ liệu. Bằng cách đó, tôi có thể tìm kiếm bất kỳ bản ghi nào trong tệp và đọc nó trực tiếp. 'là cách để đi ... cảm ơn. – mgilson

+1

FWIW, Có vẻ khó hiểu rằng' nbyte' sẽ là một thể hiện của kiểu dữ liệu khi nó thực sự chỉ hữu ích trong một mảng ... Tất nhiên, tôi cho rằng tôi không 't biết mô hình dữ liệu gumpy cũng đủ để bình luận về điều đó quá nhiều ... Dù sao, cảm ơn.Đây là những gì tôi cần thiết – mgilson

+0

Tôi đồng ý, scalars của numpy (ví dụ như 'np.float32 (5)') có thể gây nhầm lẫn. sự khác biệt giữa một vô hướng sần và một mảng numpy 0-d (ví dụ 'np.array (5, dtype = np.float32)') thậm chí còn khó hiểu hơn (Thử lập chỉ mục mảng 0-d!) ha có các thuộc tính giống như một ndarray bình thường là những thứ như 'x [5].abs() 'sẽ hoạt động chính xác cho các mảng 1d. Nó có ý nghĩa trong "bức tranh rộng hơn" nhưng nó gây ra rất nhiều sự nhầm lẫn. –

12

Nhìn vào file nguồn NumPy C, đây là những nhận xét:

size : int 
    Number of elements in the array. 
itemsize : int 
    The memory use of each array element in bytes. 
nbytes : int 
    The total number of bytes required to store the array data, 
    i.e., ``itemsize * size``. 

Vì vậy, trong NumPy:

>>> x = np.zeros((3, 5, 2), dtype=np.float64) 
>>> x.itemsize 
8 

Vì vậy .nbytes là một phím tắt cho:

>>> np.prod(x.shape)*x.itemsize 
240 
>>> x.nbytes 
240 

Vì vậy, để có được một ba se kích thước của một mảng NumPy mà không cần tạo một thể hiện của nó, bạn có thể làm điều này (giả sử một mảng 3x5x2 của đôi ví dụ):

>>> np.float64(1).itemsize * np.prod([3,5,2]) 
240 

Tuy nhiên, lưu ý quan trọng từ NumPy tập tin trợ giúp:

| nbytes 
|  Total bytes consumed by the elements of the array. 
| 
|  Notes 
|  ----- 
|  Does not include memory consumed by non-element attributes of the 
|  array object. 
+0

Bạn đã tạo một cá thể thông qua 'np.float64 (1)' là những gì tôi đang cố tránh. Lý do tôi muốn tránh nó là vì khi đọc dòng đó, người dùng có thể nói "tại sao 1?" ... trong khi thực tế, 1 không phải là đặc biệt ... Chỉ là tôi cần một thể hiện của 'np.float64' để có được các mục ... Tuy nhiên, 1 để trả lời câu hỏi thứ hai về itemsize vs nbytes (và đọc nguồn) ... – mgilson

+1

Bạn cũng có thể thực hiện 'np.float64(). itemsize'. Tuy nhiên, nếu bạn có thời gian thay thế 'np.dtype (np.float64) .itemsize' nhanh hơn một chút so với' np.float64(). Itemsize' Không quá quan trọng, nhưng đủ. Nó tóm lại những gì bạn cho là dễ đọc hơn. – dawg

+0

Thú vị ... Cảm ơn bạn đã chỉ ra rằng 'np.float64()' cũng hoạt động. – mgilson

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