অজগর: ভেরিয়েবল একটি অ্যারে বা স্কেলার হয় তা কীভাবে সনাক্ত করতে হয়


283

আমার যুক্তি রয়েছে এমন একটি ফাংশন রয়েছে NBins। আমি একটি স্কেলার 50বা একটি অ্যারে দিয়ে এই ফাংশনটিতে কল করতে চাই [0, 10, 20, 30]। আমি কিভাবে ফাংশনটির মধ্যে সনাক্ত করতে পারি, দৈর্ঘ্য কত NBins? বা অন্যভাবে বলেছে, এটি যদি কোনও স্কেলার বা ভেক্টর হয়?

আমি এটি চেষ্টা করেছি:

>>> N=[2,3,5]
>>> P = 5
>>> len(N)
3
>>> len(P)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object of type 'int' has no len()
>>> 

আপনি দেখুন, আমি আবেদন করতে পারবেন না lenকরার P, এটি একটি অ্যারে না যেহেতু .... মত সেখানে কিছু isarrayবা isscalarপাইথন মধ্যে?

ধন্যবাদ


3
আপনি কি এর জন্য পরীক্ষার চেষ্টা করেছেন type?
সুকৃত কালরা

উত্তর:


390
>>> isinstance([0, 10, 20, 30], list)
True
>>> isinstance(50, list)
False

যে কোনও ধরণের ক্রম সমর্থন করতে, collections.Sequenceপরিবর্তে পরীক্ষা করুন list

দ্রষ্টব্য : isinstanceএছাড়াও ক্লাসের একটি বড় অংশ সমর্থন করে, চেক type(x) in (..., ...)এড়ানো উচিত এবং অপ্রয়োজনীয়।

আপনি চেক করতে চান not isinstance(x, (str, unicode))


3
ধন্যবাদ, আমি list
স্কেলারের

3
যদিও এটি দুর্দান্ত উত্তর, collections.Sequenceপাশাপাশি স্ট্রিংয়ের জন্য একটি এবিসি, যাতে এটি বিবেচনায় নেওয়া উচিত। আমি এরকম কিছু ব্যবহার করছি if type(x) is not str and isinstance(x, collections.Sequence):। এটি দুর্দান্ত নয়, তবে এটি নির্ভরযোগ্য।
bbenne10

2
@ বিবেন ১০০ নিশ্চিত, তবে এড়িয়ে চলুন typeএবং not isinstance(x, (str, unicode))পাইথন ২
জ্যামাইলাক

আপনি কেন "(..., ...) তে চেক টাইপ (এক্স) এড়িয়ে চলা উচিত এবং এটি অপ্রয়োজনীয়?" আপনি যদি এমনটি বলেন, তবে এটি ব্যাখ্যা করা খুব দয়াজনক হবে কেন, সম্ভবত এ কারণটি এড়ানো উচিত বলে আমি ভাবতে পারি না কেবল আমি।
অলিভিয়ার পন্স


118

পূর্ববর্তী উত্তরগুলি ধরে নেওয়া হয় যে অ্যারেটি পাইথন স্ট্যান্ডার্ড তালিকা। যে কেউ প্রায়শই অদ্ভুত ব্যবহার করে, আমি তার জন্য খুব অজগর পরীক্ষার পরামর্শ দেব:

if hasattr(N, "__len__")

12
স্ট্রিংগুলির একটি __len__বৈশিষ্ট্য রয়েছে (সুতরাং আমি অনুমান করি, প্রযুক্তিগতভাবে কোনও স্কেলারের ধরণের নয়)
xofer

20
if hasattr(N, '__len__') and (not isinstance(N, str))স্ট্রিং জন্য সঠিকভাবে অ্যাকাউন্ট হবে।
Thucydides411


44

@ জামিলাক এবং @ জেপ্যাডিসন 3 এর উত্তরগুলি একত্রিত করে, যদি আপনাকে ইনপুট হিসাবে নপি অ্যারেগুলির বিরুদ্ধে শক্ত হয়ে ও তালিকা হিসাবে একইভাবে পরিচালনা করতে হয়, আপনার ব্যবহার করা উচিত

import numpy as np
isinstance(P, (list, tuple, np.ndarray))

এটি তালিকা, টিপল এবং আকাঙ্ক্ষিত অ্যারেগুলির সাবক্লাসগুলির বিরুদ্ধে শক্ত।

এবং আপনি যদি সিকোয়েন্সের অন্যান্য সমস্ত সাবক্লাসের বিরুদ্ধেও দৃ be় হতে চান তবে (কেবল তালিকা এবং টিপল নয়)

import collections
import numpy as np
isinstance(P, (collections.Sequence, np.ndarray))

আপনার কেন এইভাবে জিনিসগুলি করা উচিত isinstanceলক্ষ্যগুলির type(P)সাথে তুলনা না করে ? এখানে একটি উদাহরণ রয়েছে, যেখানে আমরা NewListতালিকার একটি তুচ্ছ সাবক্লাসের আচরণ এবং গবেষণা করি ।

>>> class NewList(list):
...     isThisAList = '???'
... 
>>> x = NewList([0,1])
>>> y = list([0,1])
>>> print x
[0, 1]
>>> print y
[0, 1]
>>> x==y
True
>>> type(x)
<class '__main__.NewList'>
>>> type(x) is list
False
>>> type(y) is list
True
>>> type(x).__name__
'NewList'
>>> isinstance(x, list)
True

সমান হয়েও xএবং yতুলনা করলে এগুলি পরিচালনা typeকরা বিভিন্ন আচরণের ফলস্বরূপ। যাইহোক, যেহেতু xএকটি সাবক্লাসের উদাহরণ list, isinstance(x,list)ব্যবহারটি পছন্দসই আচরণ এবং আচরণ করে xএবং দেয়y একই পদ্ধতিতে দেয়।


এটি আমার উত্তর সবচেয়ে উপযুক্ত যে উত্তর। আমি ঠিক সেটও যুক্ত করেছি। কারণ আমি ডিক্টের বিরুদ্ধে শক্ত হতে চাই না। isinstance(P, (list, tuple, set, np.ndarray))
সান্তিয়াগো

32

নাম্বারে ইস্যুকারারের সমতুল্য কি আছে? হ্যাঁ.

>>> np.isscalar(3.1)
True
>>> np.isscalar([3.1])
False
>>> np.isscalar(False)
True

6
এটি আরও ভাল এবং একটি উদাহরণ হবে: >>> np.isscalar('abcd')ফেরত True
Syrtis মেজর

ধন্যবাদ! এটি উপরের যে কোনওটির তুলনায় অনেক সাধারণ উদাহরণ এবং পছন্দ করা উচিত। এটি ওপি-র প্রশ্নের সরাসরি উত্তরও।
ক্রিস্টাবাল সিফন

1
খুশী হলাম। যদিও একটি গ্যাচা হ'ল ইস্যুকারার (কোনও নয়) মিথ্যা ফিরিয়ে দেয়। নম্পি এটিকে প্রয়োগ করেreturn (isinstance(num, generic) or type(num) in ScalarType or isinstance(num, numbers.Number))
শীতল শাহ

5
না, দুঃখের বিষয় দ্যnumpy.isscalar()ফাংশন শত্রুভাবাপন্ন নকশা সংক্রান্ত ত্রুটিগুলি একটি নম্বর ভুগছেন হবে সম্ভবত কিছু ভবিষ্যতে সংস্করণ এ উঠিয়ে নেওয়া। অফিসিয়াল ডকুমেন্টেশন প্যারাফ্রেস করতে : "প্রায় সব ক্ষেত্রে np.ndim(x) == 0পরিবর্তে ব্যবহার করা উচিত np.isscaler(x), কারণ প্রাক্তন 0 ডি অ্যারেগুলির জন্য সঠিকভাবে সত্য হিসাবে ফিরে আসবেন।" এর জন্য একটি শক্তিশালী ফরোয়ার্ড-সামঞ্জস্যপূর্ণ বিকল্পটি numpy.isscalar()হবে তুচ্ছভাবে মোড়ানো numpy.ndim(): উদাহরণস্বরূপdef is_scalar(obj): return np.ndim(obj) == 0
সিসিল কারি

আসলে এটিকে উজ্জীবিত করা উচিত নয় কারণ np.isscalarবিভ্রান্তিকর। অফিশিয়াল ডকটি np.array.ndimসর্বত্র ব্যবহারের পরামর্শ দিয়েছে , অর্থাত্ np.isscalar(np.array(12))এটি মিথ্যা, যখন এটি np.array(12).ndim0 এর থেকে স্কেলার হিসাবে বিবেচনা করা উচিত
knh190

17

@ জামিলাকের দৃষ্টিভঙ্গি আরও ভাল, যদিও এখানে বিকল্প পদ্ধতি রয়েছে

>>> N=[2,3,5]
>>> P = 5
>>> type(P) in (tuple, list)
False
>>> type(N) in (tuple, list)
True

2
উত্তরটি হ্রাসকারী ব্যক্তি যদি একটি কারণও দিতেন তবে তা দুর্দান্ত হত।
সুকৃত কালরা

আমি প্রকৃতপক্ষে upvated করেছি, কিন্তু তখন বুঝতে পেরেছি যে এটি 2.7 তে কাজ করে না: >>> পি = [] >>> (তালিকায়) টাইপ (পি) ট্রেসব্যাক (সর্বশেষতম কল শেষ): ফাইল "<স্টিডেন>" , লাইন 1, <
মডুল

@ ওলেগগ্রাইব: চেষ্টা করুন type(p) in (list, )
সুকৃত কালরা

আহ, এটি ডানদিকে একটি টিপল, একটি তালিকা নয়, এটি পেয়েছে, ধন্যবাদ এবং এটি এখন কাজ করে। আমি আফসোস করছি, আমি 2 বার
উপার্জন করতে পারি

3

অন্য বিকল্প পদ্ধতি (শ্রেণীর নামের সম্পত্তি ব্যবহার ):

N = [2,3,5]
P = 5

type(N).__name__ == 'list'
True

type(P).__name__ == 'int'
True

type(N).__name__ in ('list', 'tuple')
True

কিছু আমদানি করার দরকার নেই।


3

এখানে আমি খুঁজে পেয়েছি সেরা পদ্ধতির: __len__এবং এর অস্তিত্ব পরীক্ষা করুন__getitem__

আপনি জিজ্ঞাসা করতে পারেন কেন? কারণগুলির মধ্যে রয়েছে:

  1. জনপ্রিয় পদ্ধতি isinstance(obj, abc.Sequence)পাইটর্চের টেনসর সহ কিছু বস্তুগুলিতে ব্যর্থ হয়েছে কারণ তারা প্রয়োগ করে না__contains__
  2. দুর্ভাগ্যক্রমে, পাইথনের সংগ্রহগুলিতে এমন কিছুই নেই যা কেবল __len__এবং এর জন্য পরীক্ষা করে__getitem__ যা আমি মনে বস্তু অ্যারে-মত ন্যূনতম পদ্ধতি।
  3. এটি তালিকায় কাজ করে, টুপল, ন্যাডেরে, টেনসর ইত্যাদি

সুতরাং আর অ্যাডো ছাড়া:

def is_array_like(obj, string_is_array=False, tuple_is_array=True):
    result = hasattr(obj, "__len__") and hasattr(obj, '__getitem__') 
    if result and not string_is_array and isinstance(obj, (str, abc.ByteString)):
        result = False
    if result and not tuple_is_array and isinstance(obj, tuple):
        result = False
    return result

নোট করুন যে আমি ডিফল্ট প্যারামিটারগুলি যুক্ত করেছি কারণ বেশিরভাগ সময় আপনি স্ট্রিংগুলিকে মান হিসাবে বিবেচনা করতে চাইতে পারেন, অ্যারে নয়। একইভাবে tuples জন্য।


2
>>> N=[2,3,5]
>>> P = 5
>>> type(P)==type(0)
True
>>> type([1,2])==type(N)
True
>>> type(P)==type([1,2])
False

2

আপনি ভেরিয়েবলের ডেটা ধরণের পরীক্ষা করতে পারেন।

N = [2,3,5]
P = 5
type(P)

এটি আপনাকে পি এর ডাটা টাইপ হিসাবে দেবে।

<type 'int'>

যাতে আপনি পার্থক্য করতে পারেন যে এটি একটি পূর্ণসংখ্যা বা একটি অ্যারে।


2

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

আমার জন্য, এর চেয়ে ভাল যা কাজ করে তা হ'ল নামী আমদানি করা এবং অ্যারে ব্যবহার করা s সাইজ, উদাহরণস্বরূপ:

>>> a=1
>>> np.array(a)
Out[1]: array(1)

>>> np.array(a).size
Out[2]: 1

>>> np.array([1,2]).size
Out[3]: 2

>>> np.array('125')
Out[4]: 1

এছাড়াও নোট:

>>> len(np.array([1,2]))

Out[5]: 2

কিন্তু:

>>> len(np.array(a))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-40-f5055b93f729> in <module>()
----> 1 len(np.array(a))

TypeError: len() of unsized object

আমি আরও অবাক হয়েছি যে তাদের কেউই জেনারেটরের সাথেও व्यवहार করে না বলে মনে হয়।
RhysC

2

কেবল sizeপরিবর্তে ব্যবহার করুন len!

>>> from numpy import size
>>> N = [2, 3, 5]
>>> size(N)
3
>>> N = array([2, 3, 5])
>>> size(N)
3
>>> P = 5
>>> size(P)
1

2
নামের ত্রুটি: নাম 'আকার' সংজ্ঞায়িত করা হয়নি
থ্যাং করুন

1
সেটা সত্য. আমি এটিকে লক্ষ্য না করেই অদ্ভুত আকার ব্যবহার করছিলাম। আপনার প্রয়োজন: ন্যালি আমদানি আকার থেকে
ম্যাথিউ ভিলিয়ন

2
np.size(5)এবং np.size([5])উভয়ই == 1, সুতরাং এটি সঠিকভাবে ধরণের (যেমন একটি স্কেলারের শনাক্তকরণ) আলাদা করে না, যা আমার বিশ্বাস লক্ষ্য।
মাইকেল 25

এটি একটি আকর্ষণীয় মন্তব্য। আসল প্রশ্ন ইস্যুকারারকে বোঝায় যা একটি মতলব ফাংশন। মতলবতে, স্কেলার এবং আকার 1 এর অ্যারের মধ্যে একেবারেই কোনও পার্থক্য নেই, এটি ভেক্টর বা এন-ম্লাদ অ্যারে হতে পারে। আইএমএইচও, এটি মাতলাবের জন্য একটি প্লাস।
ম্যাথিউ ভিলিয়ন

0

preds_test [0] আকৃতির (128,128,1) আইসাইনস্ট্যান্স () ফাংশন ব্যবহার করে এর ডেটা টাইপ পরীক্ষা করতে দেয় আইসনস্ট্যান্স 2 টি আর্গুমেন্ট নেয় takes প্রথম আর্গুমেন্টটি ডেটা ২ য় যুক্তি হ'ল ডেটা টাইপ আইসিনস্ট্যান্স (প্রেস্ট_স্টেস্ট [0], এনপি.অ্যান্ডারায়) আউটপুটকে সত্য হিসাবে দেয়। এর অর্থ preds_test [0] একটি অ্যারে।


0

শিরোনামে প্রশ্নের উত্তর দেওয়ার জন্য, ভেরিয়েবলটি স্কেলার কিনা তা জানানোর সরাসরি উপায় হ'ল এটিকে একটি ফ্লোটে রূপান্তরিত করার চেষ্টা করা। যদি আপনি পান TypeError, এটি না।

N = [1, 2, 3]
try:
    float(N)
except TypeError:
    print('it is not a scalar')
else:
    print('it is a scalar')
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.