ন্যাপি টাইপগুলি দেশীয় অজগর প্রকারে রূপান্তর করা


238

আমার যদি একটি নম্পুটি টাইপ থাকে তবে আমি কীভাবে এটি স্বয়ংক্রিয়ভাবে এটির নিকটতম পাইথন ডেটা টাইপে রূপান্তর করব? উদাহরণ স্বরূপ,

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

আমি এই সমস্ত ক্ষেত্রে একটি ম্যাপিং নিয়ে আসতে চেষ্টা করতে পারি, তবে কি নম্পি তার ডাইটিপগুলি নিকটতম সম্ভাব্য নেটিভ অজগর জাতগুলিতে রূপান্তর করার কোনও স্বয়ংক্রিয় উপায় সরবরাহ করে? এই ম্যাপিংটি পরিস্ফুটিত হওয়ার দরকার নেই, তবে এটি সাধারণ ধরণের টাইপগুলিকে রূপান্তর করা উচিত যাগুলির নিকট পাইথন অ্যানালগ রয়েছে। আমি মনে করি এটি ইতিমধ্যে কোথাও অদ্ভুতভাবে ঘটেছিল।

উত্তর:


325

val.item()সর্বাধিক NumPy মানগুলিকে একটি পাইথন টাইপে রূপান্তর করতে ব্যবহার করুন :

import numpy as np

# for example, numpy.float32 -> python float
val = np.float32(0)
pyval = val.item()
print(type(pyval))         # <class 'float'>

# and similar...
type(np.float64(0).item()) # <class 'float'>
type(np.uint32(0).item())  # <class 'long'>
type(np.int16(0).item())   # <class 'int'>
type(np.cfloat(0).item())  # <class 'complex'>
type(np.datetime64(0, 'D').item())  # <class 'datetime.date'>
type(np.datetime64('2001-01-01 00:00:00').item())  # <class 'datetime.datetime'>
type(np.timedelta64(0, 'D').item()) # <class 'datetime.timedelta'>
...

(অন্য একটি পদ্ধতি হ'ল np.asscalar(val)এটি NumPy 1.16 সাল থেকে অবচিত করা হয়েছে)।


কৌতূহলের জন্য, আপনার সিস্টেমের জন্য NumPy অ্যারে স্কেলারগুলির রূপান্তরগুলির একটি সারণী তৈরি করতে :

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

কয়েকটি NumPy ধরনের আছে সহ কিছু সিস্টেম, কোন নেটিভ পাইথন সমতুল্য আছেন: clongdouble, clongfloat, complex192, complex256, float128, longcomplex, longdoubleএবং longfloat। এগুলি ব্যবহারের আগে তাদের নিকটতম NumPy সমতুল্যে রূপান্তর করা দরকার .item()


আমি পান্ডাস (0.23.0) ব্যবহার করছি। কমপক্ষে সেই সংস্করণটির জন্য, এনপি.স্ট্রিমে .item () পদ্ধতি নেই তাই আমি দেখেছি কেবলমাত্র একটি উপায় চেষ্টা ব্লকের ভিতরে .item () মোড়ানো।
রবার্ট লাগেজ

3
@ রবার্টলগ np.strকোনও নম্পি টাইপ নয়, অর্থাত্ np.str is strএটি স্ট্যান্ডার্ড পাইথন টাইপের কেবলমাত্র একটি নাম। সঙ্গে একই np.float, np.int, np.bool, np.complex, এবং np.object। নম্পি ধরণের একটি পেছন রয়েছে _, যেমন np.str_
মাইক টি

আমি বুঝেছি. সুতরাং বিষয়টি হ'ল "ভাল লাগবে যদি" ​​আমি করতে পারতাম: np.float64(0).item()এবং এটিও np.float(0).item()। অন্য কথায়, যে ক্ষেত্রে কী করা উচিত তা জানা যায়, .item()পদ্ধতিটি যদি কেবল একই মানটি দেয় তবে তা সমর্থন করুন । এই পদ্ধতিতে আমি .item()বিশেষ কেসিং ছাড়াই আরও অনেক বেশি নাম্পার স্কেলারে আবেদন করতে পারি । যেমনটি হয়, অন্তর্নিহিত বাস্তবায়নের কারণে আপাতদৃষ্টিতে সমান্তরাল ধারণাগুলি পৃথক হয়। কেন করা হয়েছিল তা আমি পুরোপুরি বুঝতে পারি। তবে এটি গ্রন্থাগার ব্যবহারকারীর বিরক্তি।
রবার্ট লাগ

45

নিজেকে ন্যাপি টাইপ এবং স্ট্যান্ডার্ড পাইথনের মিশ্রিত সেট পেয়েছি। সমস্ত অদ্ভুত প্রকার থেকে প্রাপ্ত numpy.generic, এখানে আপনি কীভাবে সমস্ত কিছু পাইথন স্ট্যান্ডার্ড ধরণের রূপান্তর করতে পারেন তা এখানে:

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

5
গৃহীত উত্তর নোট হিসাবে , NumPy 1.16 np.asscalar()পদ্ধতি অবমূল্যায়ন । কেন? সম্ভবত কোনও স্পষ্টতই ভাল কারণ নেই। আপেক্ষিক স্থিতিশীলতার দশক সত্ত্বেও, নিমপাই এপিআই এখন ডাউন স্ট্রিম অ্যাপ্লিকেশনগুলি থেকে ধ্রুবক রক্ষণাবেক্ষণের বাধ্যতামূলক একটি অস্থির চলন্ত লক্ষ্য। কমপক্ষে তারা আমাদের জন্য আপাততitem() পদ্ধতিটি রেখে দিয়েছে ...
সিসিল কারি

asscalar পদ্ধতি numpy এর v1.6 যেহেতু মূল্যমান হ্রাস করেছে
Eswar

আপনি উত্তরটি সহজেই এর সাথে প্রতিস্থাপন করতে পারেন if isinstance(o, numpy.generic): return o.item() raise TypeErrorএবং এটি আবার অ-প্রত্যাশিত উত্তরে পরিণত হয়: ডি
বগি

19

আপনি যদি (numpy.array বা numpy Scalar বা নেটিভ টাইপ OR numpy.darray) রূপান্তর করতে চান তবে টাইপ করতে পারেন:

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

টোলিস্ট আপনার স্কেলার বা অ্যারেটিকে পাইথন নেটিভ টাইপে রূপান্তর করবে। ডিফল্ট ল্যাম্বদা ফাংশন সেই ক্ষেত্রে যত্ন নেবে যেখানে মানটি ইতিমধ্যে দেশীয়।


2
মিশ্র প্রকারের (দেশীয় এবং অ-নেটিভ) জন্য সবচেয়ে ভাল পদ্ধতির, ভালভাবে সম্পন্ন! এবং তাদের অবাক করে দেওয়ার জন্য, হ্যাঁ, টোলিস্ট কেবলমাত্র একটি একক মান (স্কেলার) ফিরিয়ে দেয় যখন আপনি এটি ভেবেছিলেন এমন কোনও তালিকা নয়, একটি মানকে কল করে। লক্ষণীয় বিষয় হ'ল ল্যাম্বদা লেখার সহজ উপায় হ'ল lambda: valueযেহেতু আমরা কোনও ইনপুট চাই না।
fgblomqvist

getattr+ tolistকম্বো কেবল সর্বজনীন নয়, এমনকি ভেক্টরাইজডও! (আনলিঙ্ক .item ())
মাইরেকএফডি

11

কেমন:

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
আমি আমার প্রশ্নের শেষে সম্ভাবনা হিসাবে এই ধরণের সমাধান উল্লেখ করি। তবে আমি একটি হার্ড-কোডেড সমাধানের চেয়ে পদ্ধতিগত সমাধানের সন্ধান করছি যা কয়েকটি ক্ষেত্রে কেবল আবৃত। উদাহরণস্বরূপ, যদি নম্পি ভবিষ্যতে আরও ডাইপ টাইপ যোগ করে তবে আপনার সমাধানটি ভেঙে যাবে। সুতরাং আমি সেই সমাধানে খুশি নই।
কনরাডলি

সম্ভাব্য টাইপগুলির সংখ্যা সীমাহীন। np.dtype('mint8')যেকোন ধনাত্মক পূর্ণসংখ্যার জন্য বিবেচনা করুন m। একটি সম্পূর্ণ ম্যাপিং করা যাবে না। (আমি এও বিশ্বাস করেন না আপনার জন্য এই রূপান্তর করতে একটি builtin ফাংশন আছে আমি ভুল হতে পারে না, কিন্তু আমি তা মনে করি না :)।)
unutbu

2
পাইথন অজগর টাইপগুলিকে অজগর টাইপের মানচিত্র দেয়, আমি কীভাবে তা নিশ্চিত নই, তবে তারা যে কোনও পদ্ধতিই ব্যবহার করতে চাই। আমি মনে করি এটির অবশ্যই অবশ্যই এটির জন্য অবশ্যই নপি ডাইটিপস এবং পাইথনের ধরণের মধ্যে গুণন (এবং অন্যান্য ক্রিয়াকলাপ) প্রযোজ্য। আমি অনুমান করি যে তাদের পদ্ধতিটি সমস্ত সম্ভাব্য আকাঙ্ক্ষিত প্রকারের সংক্ষিপ্ত বিবরণে মানচিত্র তৈরি করে না, তবে এটি যেখানে উপলব্ধি করে সেখানে অন্ততপক্ষে সবচেয়ে সাধারণ বিষয়।
কনড্রালি

এটি ধারাবাহিকভাবে কাজ করে না: >>> print([numpy.asscalar(x) for x in numpy.linspace(1.0, 0.0, 21)]) [1.0, 0.95, 0.9, 0.85, 0.8, 0.75, 0.7, 0.6499999999999999, 0.6, 0.55, 0.5, 0.44999999999999996, 0.3999999999999999, 0.35, 0.29999999999999993, 0.25, 0.19999999999999996, 0.1499999999999999, 0.09999999999999998, 0.04999999999999993, 0.0]আপনি দেখতে পাচ্ছেন না সমস্ত মান সঠিকভাবে রূপান্তরিত হয়েছিল।
অ্যালেক্স এফ

আমার আগের মন্তব্যের পরে, আশ্চর্যরূপে এইটি একটি কাজ করে, যদিও আমার কাছে আপনাকে নম্পি নেটিভ টাইপের পরিবর্তে পাইথন নেটিভ টাইপের উপর গোল করা প্রয়োজন: >>> print([numpy.asscalar(round(x,2)) for x in numpy.linspace(1.0, 0.0, 21)]) [1.0, 0.95, 0.9, 0.85, 0.8, 0.75, 0.7, 0.65, 0.6, 0.55, 0.5, 0.45, 0.4, 0.35, 0.3, 0.25, 0.2, 0.15, 0.1, 0.05, 0.0]
অ্যালেক্স এফ

9

tolist()এটি সম্পাদন করার জন্য আরও সাধারণ পদ্ধতি। এটি যে কোনও আদিম টাইপ এবং অ্যারে বা ম্যাট্রিক্সেও কাজ করে।

আদিম ধরণের থেকে ডাকা হলে আমি আসলে একটি তালিকা পাই না:

অদ্ভুত == 1.15.2

>>> import numpy as np

>>> np_float = np.float64(1.23)
>>> print(type(np_float), np_float)
<class 'numpy.float64'> 1.23

>>> listed_np_float = np_float.tolist()
>>> print(type(listed_np_float), listed_np_float)
<class 'float'> 1.23

>>> np_array = np.array([[1,2,3.], [4,5,6.]])
>>> print(type(np_array), np_array)
<class 'numpy.ndarray'> [[1. 2. 3.]
 [4. 5. 6.]]

>>> listed_np_array = np_array.tolist()
>>> print(type(listed_np_array), listed_np_array)
<class 'list'> [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]


6

আমি মনে করি আপনি কেবল সাধারণ ধরণের রূপান্তর ফাংশন লিখতে পারেন:

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'>)

এর অর্থ কোনও স্থির তালিকা নেই এবং আপনার কোড আরও প্রকারের সাথে স্কেল করবে।


আপনি কি জানেন যে টোলিস্ট () পদ্ধতির অংশের জন্য উত্স কোডটি রয়েছে যেখানে অজগর প্রকারে অদৃশ্য প্রকারের মানচিত্র রয়েছে? আমি তাত্ক্ষণিকভাবে দেখেছি কিন্তু এটি খুঁজে পেল না।
22:55 এ কনড্রালি

এটি হ্যাকের একটি বিষয় যা আমি করছি numpy.ndarrayএটির সাথে 1 জিরো ব্যবহার করে zeros()এবং কলিংটি একটি জেনারেট করেndarrays tolist() ফাংশনটিকে কল্পনা করে দেশীয় ধরণের রূপান্তর করতে। একবার দেশীয় প্রকারে আমি টাইপটি এটির জন্য চাই ask tolist()এটি হ'লndarray
ম্যাট অ্যালকক

হ্যাঁ আমি এটি দেখতে পাচ্ছি --- এটি আমার যা ইচ্ছা তা কাজ করে এবং তাই আমি আপনার সমাধানটি গ্রহণ করেছি। তবে আমি অবাক হয়েছি যে টোলিস্ট () কী ধরণের কাস্ট করতে হবে তার সিদ্ধান্ত নেওয়ার কাজটি কী করে এবং উত্সটি কীভাবে সন্ধান করতে হয় তা সম্পর্কে আমি নিশ্চিত নই।
22:30 এ কনরাডলি

numpy.sourceforge.net/numdoc/HTML/numdoc.htm#pgfId-36588 যেখানে ফাংশন ডকুমেন্ট করা আছে। আমি ভেবেছিলাম পরিদর্শন আরও তথ্য সন্ধান করতে সক্ষম হতে পারে তবে কোনও আনন্দ নেই। পরবর্তী পদক্ষেপে আমি github.com/numpy/numpy.git ক্লোন করে চালানোর চেষ্টা করেছি grep -r 'tolist' numpy। (এখনও অগ্রগতি, numpy বৃহদায়তন হয়!)
ম্যাট Alcock

3

নম্পি এই তথ্যটিকে ম্যাপিংয়ে উন্মোচিত করেছে typeDictযাতে আপনি নীচের মতো কিছু করতে পারেন ::

>>> 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'}

যদি আপনি প্রকৃত পাইথনগুলির নামগুলির পরিবর্তে তাদের নামগুলি চান তবে আপনি এটি করতে পারেন ::

>>> {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

আংশিকভাবে দেরীতে এসে দুঃখিত, তবে আমি কেবল numpy.float64নিয়মিত পাইথনে রূপান্তরিত করার সমস্যাটির দিকে চেয়েছিলাম float। আমি এটি করার 3 টি উপায় দেখেছি:

  1. npValue.item()
  2. npValue.astype(float)
  3. float(npValue)

আইপিথন থেকে প্রাসঙ্গিক সময় এখানে:

In [1]: import numpy as np

In [2]: aa = np.random.uniform(0, 1, 1000000)

In [3]: %timeit map(float, aa)
10 loops, best of 3: 117 ms per loop

In [4]: %timeit map(lambda x: x.astype(float), aa)
1 loop, best of 3: 780 ms per loop

In [5]: %timeit map(lambda x: x.item(), aa)
1 loop, best of 3: 475 ms per loop

মত শোনাচ্ছে float(npValue)অনেক দ্রুত বলে মনে হয়।


1

আমার পদ্ধতির বিষয়টি কিছুটা জোরালো, তবে মনে হয় এটি সমস্ত ক্ষেত্রেই দুর্দান্ত খেলবে:

def type_np2py(dtype=None, arr=None):
    '''Return the closest python type for a given numpy dtype'''

    if ((dtype is None and arr is None) or
        (dtype is not None and arr is not None)):
        raise ValueError(
            "Provide either keyword argument `dtype` or `arr`: a numpy dtype or a numpy array.")

    if dtype is None:
        dtype = arr.dtype

    #1) Make a single-entry numpy array of the same dtype
    #2) force the array into a python 'object' dtype
    #3) the array entry should now be the closest python type
    single_entry = np.empty([1], dtype=dtype).astype(object)

    return type(single_entry[0])

ব্যবহার:

>>> type_np2py(int)
<class 'int'>

>>> type_np2py(np.int)
<class 'int'>

>>> type_np2py(str)
<class 'str'>

>>> type_np2py(arr=np.array(['hello']))
<class 'str'>

>>> type_np2py(arr=np.array([1,2,3]))
<class 'int'>

>>> type_np2py(arr=np.array([1.,2.,3.]))
<class 'float'>

আমি দেখতে পাচ্ছি যে এটি ম্যাট অ্যালককের উত্তরের মতোই।
সাইমন স্ট্রাইচার

1

তাদের জন্য অ্যারে স্কেলারগুলি সম্পর্কে একটি পার্শ্ব নোট যাঁদের স্বয়ংক্রিয় রূপান্তর প্রয়োজন হয় না এবং মানটির অকার্যকর টাইপ জানেন:

অ্যারে স্কেলারগুলি পাইথন স্কেলারের থেকে পৃথক, তবে বেশিরভাগ অংশে এগুলি বিনিময়যোগ্যভাবে ব্যবহার করা যেতে পারে (প্রাথমিক ব্যতিক্রম পাইথনের সংস্করণ v2.x এর চেয়ে পুরানো, যেখানে পূর্ণসংখ্যার অ্যারে স্কেলারগুলি তালিকা এবং টিপলসের সূচক হিসাবে কাজ করতে পারে না)। কিছু ব্যতিক্রম রয়েছে, যেমন কোডের জন্য যখন কোনও স্কেলারের খুব সুনির্দিষ্ট বৈশিষ্ট্য প্রয়োজন হয় বা যখন এটি নির্দিষ্টভাবে পরীক্ষা করে থাকে যে কোনও মান পাইথন স্কেলার কিনা। সাধারণত, পাইথন টাইপ ফাংশন (উদাহরণস্বরূপ, ইনট, ফ্লোট, কমপ্লেক্স, স্ট্রিং, ইউনিকোড) ব্যবহার করে সহজেই অ্যারে স্ক্যালারগুলিকে পাইথন স্কেলারে রূপান্তরিত করে সমস্যাগুলি সহজেই সংশোধন করা হয়।

উৎস

সুতরাং, বেশিরভাগ ক্ষেত্রে রূপান্তরটি মোটেই প্রয়োজন হয় না এবং অ্যারে স্কেলারটি সরাসরি ব্যবহার করা যেতে পারে। পাইথন স্কেলার ব্যবহারের সাথে প্রভাবটি একরকম হওয়া উচিত:

>>> np.issubdtype(np.int64, int)
True
>>> np.int64(0) == 0
True
>>> np.issubdtype(np.float64, float)
True
>>> np.float64(1.1) == 1.1
True

তবে, যদি কোনও কারণে, সুস্পষ্ট রূপান্তর প্রয়োজন হয়, তবে পাইথন অন্তর্নির্মিত ফাংশনটি ব্যবহার করার উপায়টি। অন্য উত্তরে যেমন দেখানো হয়েছে এটি অ্যারে স্কেলার item()পদ্ধতি থেকেও দ্রুত ।


0

এক ইউনিট ডেটা অবজেক্টের পরিবর্তে পুরো নাদারের অনুবাদ করুন:

def trans(data):
"""
translate numpy.int/float into python native data type
"""
result = []
for i in data.index:
    # i = data.index[0]
    d0 = data.iloc[i].values
    d = []
    for j in d0:
        if 'int' in str(type(j)):
            res = j.item() if 'item' in dir(j) else j
        elif 'float' in str(type(j)):
            res = j.item() if 'item' in dir(j) else j
        else:
            res = j
        d.append(res)
    d = tuple(d)
    result.append(d)
result = tuple(result)
return result

তবে বড় ডেটা ফ্রেমগুলি পরিচালনা করতে কয়েক মিনিট সময় লাগে। আমি আরও কার্যকর সমাধানের সন্ধান করছি। আরও ভাল উত্তর আশা করি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.