2012-02-26 26 views
109

Nếu tôi có kiểu chữ đậm, làm cách nào để tự động chuyển đổi nó thành kiểu dữ liệu trăn gần nhất? Ví dụ,Chuyển đổi các kiểu gõ vần sang kiểu trăn bản địa

numpy.float32 -> "python float" 
numpy.float64 -> "python float" 
numpy.uint32 -> "python int" 
numpy.int16 -> "python int" 

tôi có thể cố gắng để đưa ra một bản đồ của tất cả các trường hợp, nhưng không NumPy cung cấp một số cách tự động chuyển đổi dtypes của nó thành các loại trăn có nguồn gốc có thể gần gũi nhất? Ánh xạ này không cần phải đầy đủ, nhưng nó nên chuyển đổi các kiểu dtypes chung có tương tự python gần. Tôi nghĩ rằng điều này đã xảy ra ở đâu đó trong numpy.

Trả lời

149

Sử dụng một trong hai a.item() hoặc np.asscalar(a) để chuyển đổi hầu hết các giá trị NumPy đến một loại Python bản địa:

import numpy as np 
# examples using a.item() 
type(np.float32(0).item()) # <type 'float'> 
type(np.float64(0).item()) # <type 'float'> 
type(np.uint32(0).item()) # <type 'long'> 
# examples using np.asscalar(a) 
type(np.asscalar(np.int16(0))) # <type 'int'> 
type(np.asscalar(np.cfloat(0))) # <type 'complex'> 
type(np.asscalar(np.datetime64(0, 'D'))) # <type 'datetime.datetime'> 
type(np.asscalar(np.timedelta64(0, 'D'))) # <type 'datetime.timedelta'> 
... 

Read more in the NumPy manual. Đối với người hiếu, để xây dựng một bảng chuyển đổi cho hệ thống của bạn:

for name in dir(np): 
    obj = getattr(np, name) 
    if hasattr(obj, 'dtype'): 
     try: 
      if 'time' in name: 
       npn = obj(0, 'D') 
      else: 
       npn = obj(0) 
      nat = npn.item() 
      print('{0} ({1!r}) -> {2}'.format(name, npn.dtype.char, type(nat))) 
     except: 
      pass 

Có một vài loại NumPy rằng không có Python có nguồn gốc tương đương trên một số hệ thống, bao gồm: clongdouble, clongfloat, complex192, complex256, float128, longcomplex , longdoublelongfloat. Những thứ này cần phải được chuyển đổi sang số tương đương gần nhất của NumPy trước khi sử dụng asscalar.

9

Làm thế nào về:

In [51]: dict([(d, type(np.zeros(1,d).tolist()[0])) for d in (np.float32,np.float64,np.uint32, np.int16)]) 
Out[51]: 
{<type 'numpy.int16'>: <type 'int'>, 
<type 'numpy.uint32'>: <type 'long'>, 
<type 'numpy.float32'>: <type 'float'>, 
<type 'numpy.float64'>: <type 'float'>} 
+1

Tôi đề cập đến loại giải pháp đó là khả năng ở cuối câu hỏi của tôi. Nhưng tôi đang tìm một giải pháp có hệ thống hơn là một giải pháp được mã hóa cứng chỉ bao gồm một vài trường hợp. Ví dụ, nếu numpy thêm dtypes hơn trong tương lai, giải pháp của bạn sẽ phá vỡ.Vì vậy, tôi không hài lòng với giải pháp đó. – conradlee

+0

Số lượng dtypes có thể không bị chặn. Hãy xem xét 'np.dtype ('mint8')' cho bất kỳ số nguyên dương 'm' nào. Không thể có một bản đồ toàn diện. (Tôi cũng không tin rằng có một hàm dựng sẵn để thực hiện chuyển đổi này cho bạn. Tôi có thể sai, nhưng tôi không nghĩ vậy :)) – unutbu

+2

Bản đồ Python numpy dtypes với các loại trăn, tôi không chắc chắn như thế nào, nhưng Tôi muốn sử dụng bất cứ phương pháp nào họ làm. Tôi nghĩ rằng điều này phải xảy ra để cho phép, ví dụ, nhân (và các hoạt động khác) giữa dtypes numpy và các loại python. Tôi đoán phương pháp của họ không vẽ sơ đồ tất cả các loại có thể sần sùi, nhưng ít nhất là các phương thức phổ biến nhất có ý nghĩa. – conradlee

4

Tôi nghĩ rằng bạn chỉ có thể viết hàm gõ convert chung chung như vậy:

import numpy as np 

def get_type_convert(np_type): 
    convert_type = type(np.zeros(1,np_type).tolist()[0]) 
    return (np_type, convert_type) 

print get_type_convert(np.float32) 
>> (<type 'numpy.float32'>, <type 'float'>) 

print get_type_convert(np.float64) 
>> (<type 'numpy.float64'>, <type 'float'>) 

Điều này có nghĩa là không có danh sách cố định và mã của bạn sẽ mở rộng với nhiều loại.

+0

Bạn có biết mã nguồn nằm ở đâu trong phần của phương thức tolist() ánh xạ các kiểu numpy tới các kiểu python không? Tôi nhìn nhanh nhưng không thể tìm thấy nó. – conradlee

+0

Đây là một chút của một hack những gì tôi đang làm là tạo ra một 'numpy.ndarray' với 1 số không trong nó bằng cách sử dụng' zeros() 'và gọi hàm' ndarrays'' tolist() 'để chuyển đổi thành kiểu gốc . Một khi trong các loại bản địa tôi yêu cầu loại trả lại nó. 'tolist()' là một fucntion của 'ndarray' –

+0

Vâng tôi thấy rằng --- nó hoạt động cho những gì tôi muốn và vì vậy tôi đã chấp nhận giải pháp của bạn. Nhưng tôi tự hỏi làm thế nào tolist() hiện công việc của mình quyết định loại để đúc vào, và tôi không chắc chắn làm thế nào để tìm nguồn. – conradlee

18

tìm thấy bản thân mình có bộ hỗn hợp các loại gumpy và python chuẩn. như tất cả các loại NumPy xuất phát từ numpy.generic, dưới đây là cách bạn có thể chuyển đổi tất cả mọi thứ để trăn loại tiêu chuẩn:

if isinstance(obj, numpy.generic): 
    return numpy.asscalar(obj) 
4

Bạn cũng có thể gọi item() method của đối tượng bạn muốn chuyển đổi:

>>> from numpy import float32, uint32 
>>> type(float32(0).item()) 
<type 'float'> 
>>> type(uint32(0).item()) 
<type 'long'> 
1

NumPy cho rằng thông tin trong bản đồ được hiển thị dưới dạng typeDict để bạn có thể làm điều gì đó như bên dưới ::

>>> import __builtin__ 
>>> import numpy as np 
>>> {v: k for k, v in np.typeDict.items() if k in dir(__builtin__)} 
{numpy.object_: 'object', 
numpy.bool_: 'bool', 
numpy.string_: 'str', 
numpy.unicode_: 'unicode', 
numpy.int64: 'int', 
numpy.float64: 'float', 
numpy.complex128: 'complex'} 

Nếu bạn muốn pyt thực tế loại hon chứ không phải tên của họ, bạn có thể làm ::

>>> {v: getattr(__builtin__, k) for k, v in np.typeDict.items() if k in vars(__builtin__)} 
{numpy.object_: object, 
numpy.bool_: bool, 
numpy.string_: str, 
numpy.unicode_: unicode, 
numpy.int64: int, 
numpy.float64: float, 
numpy.complex128: complex} 
3

Nếu bạn muốn chuyển đổi (numpy.array HOẶC vô hướng NumPy HOẶC loại có nguồn gốc HOẶC numpy.darray) ĐẾN loại có nguồn gốc bạn chỉ có thể làm:

converted_value = getattr(value, "tolist", lambda x=value: x)() 

tolist sẽ chuyển đổi vô hướng hoặc mảng thành python kiểu gốc. Hàm lambda mặc định sẽ xử lý trường hợp giá trị đã có sẵn.

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