একটি NumPy অ্যারে কমপক্ষে একটি অ-সংখ্যাসূচক মান আছে কিনা তা সনাক্ত করুন?


109

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

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

এটি ঠিক কাজ করে, তবে এটি বেশ ধীর এবং আমি প্রত্যাশা করি যে এটি করার জন্য নম্পপি আরও অনেক ভাল উপায় আছে। দ্রুত এবং আরও অসম্পূর্ণ একটি বিকল্প কি?

এখানে আমার উপহাস:

def contains_nan( myarray ):
    """
    @param myarray : An n-dimensional array or a single float
    @type myarray : numpy.ndarray, numpy.array, float
    @returns: bool
    Returns true if myarray is numeric or only contains numeric values.
    Returns false if at least one non-numeric value exists
    Not-A-Number is given by the numpy.isnan() function.
    """
    return True

4
আপনার বিবরণ contains_nanসন্দেহজনক দেখাচ্ছে বলে মনে হচ্ছে: "কমপক্ষে একটি অ-সংখ্যাযুক্ত মান উপস্থিত থাকলে মিথ্যা ফিরিয়ে দেয়"। অ্যারেটিতে NaN থাকলে আমি contains_nanফিরে আসব বলে প্রত্যাশা করতাম True
স্যামুয়েল তারদিউ

যেমন ইনপুট সম্পর্কে কি array(['None', 'None'], dtype=object)? যেমন একটি ইনপুট কেবল একটি ব্যতিক্রম বাড়াতে হবে?
ফিন অরুপ নীলসন

ব্যবহার করবেন না float('nan') in x। এটা কাজ করে না.
চার্লি পার্কার

উত্তর:


195

এটি পুনরাবৃত্তির চেয়ে দ্রুত হওয়া উচিত এবং আকারটি নির্বিশেষে কাজ করবে।

numpy.isnan(myarray).any()

সম্পাদনা: 30x দ্রুত:

import timeit
s = 'import numpy;a = numpy.arange(10000.).reshape((100,100));a[10,10]=numpy.nan'
ms = [
    'numpy.isnan(a).any()',
    'any(numpy.isnan(x) for x in a.flatten())']
for m in ms:
    print "  %.2f s" % timeit.Timer(m, s).timeit(1000), m

ফলাফল:

  0.11 s numpy.isnan(a).any()
  3.75 s any(numpy.isnan(x) for x in a.flatten())

বোনাস: এটি নন-অ্যারে নুমপি টাইপগুলির জন্য সূক্ষ্মভাবে কাজ করে:

>>> a = numpy.float64(42.)
>>> numpy.isnan(a).any()
False
>>> a = numpy.float64(numpy.nan)
>>> numpy.isnan(a).any()
True

4
ন্যালি ১. with সহ ফ্ল্যাট () সংস্করণটি প্রথমটির চেয়ে দ্বিগুণ দ্রুত
খ্রিস্টান গিয়ের

float('nan') in xকাজ না করার মতো কিছু কেন ? আমি চেষ্টা করেছিলাম এবং পাইথন Falseযেখানে ফিরে আসে x = [1,2,3,float('nan')]
চার্লি পার্কার

4
@ চর্লিপার্কার একই কারণেই ভাসা ('নান') == ফ্লোট ('নান') মিথ্যা ফিরিয়ে দেবে। NaN NaN এর সমান হয় না। এখানে আরও তথ্য: স্ট্যাকওভারফ্লো.com
ম্যাপেট

4
@ এমএবি: কারণ numpy.anyজিনে এক্সপ্রেসে কল করা ঠিক জিনেক্সকে রিটার্ন দেয়; আপনি যে গণনাটি মনে করেন আপনি আসলে তা করছেন না। numpy.anyজেন এক্সপ্রেসে কখনও কল করবেন না।
ব্যবহারকারী 2357112

4
আগ্রহের বাইরে - এটি করার এটি কি দ্রুততম উপায়? i) numpy.isnan(a).any()কোনও বড় অস্থায়ী অ্যারে বরাদ্দ করা জড়িত না (এটি এটি একটি দৃশ্য)। ii) প্রথম উপাদানটি যদি ন্যান হয় তবে এই সমাধানটি কি পুরো অ্যারেতে পুনরাবৃত্তি জড়িত? যদি আমি এনএএন-তে প্রথম উপাদানটি সেট করি, এটি এখনও প্রায় 5 মাইক্রোসেকেন্ডে লাগে, যা অ্যারে অনুসন্ধান এবং পরীক্ষা দিয়ে কী করা যায় তার জন্য বেশ ধীর বলে মনে হয় - ন্যানোসেকেন্ডগুলি হওয়া উচিত, না?
ব্যবহারকারী 48956

18

যদি অসীম সম্ভাব্য মান হয় তবে আমি numpy.isftimate ব্যবহার করব

numpy.isfinite(myarray).all()

যদি উপরেরগুলি যদি মূল্যায়ণ করে Trueতবে তার myarrayমধ্যে নেই numpy.nan, numpy.infবা -numpy.infমান থাকে।

numpy.nannumpy.infমানগুলির সাথে ঠিক থাকবে , উদাহরণস্বরূপ:

In [11]: import numpy as np

In [12]: b = np.array([[4, np.inf],[np.nan, -np.inf]])

In [13]: np.isnan(b)
Out[13]: 
array([[False, False],
       [ True, False]], dtype=bool)

In [14]: np.isfinite(b)
Out[14]: 
array([[ True, False],
       [False, False]], dtype=bool)

float('nan') in xকাজ না করার মতো কিছু কেন ? আমি চেষ্টা করেছিলাম এবং পাইথন Falseযেখানে ফিরে আসে x = [1,2,3,float('nan')]
চার্লি পার্কার

4
@ চর্লিপারপারার, কারণ দু'জনকে nanএকে অপরের সমান মনে করা হয় না। ব্যবহার করে দেখুন float('nan') == float('nan')
আকাওয়াল

মজাদার. কেন তাদের সমান বিবেচনা করা হয় না?
চার্লি পার্কার

4
@ চার্লিপার্কার, আমি মনে করি না যে আমি এখানে খুব ভাল উত্তর দিতে পারি। : হয়তো এই আপনি যা খুঁজছেন হয় stackoverflow.com/questions/1565164/...
Akavall

6

পিএফটি! মাইক্রোসেকেন্ড! মাইক্রোসেকেন্ডে কখনও কোনও সমস্যার সমাধান করবেন না যা ন্যানোসেকেন্ডগুলিতে সমাধান করা যেতে পারে।

নোট করুন যে গৃহীত উত্তর:

  • কোনও ন্যান পাওয়া গেছে কিনা তা বিবেচনা না করে পুরো ডেটা ধরে পুনরাবৃত্তি করে
  • আকারের একটি অস্থায়ী অ্যারে তৈরি করে, যা অপ্রয়োজনীয়।

আরও ভাল সমাধান হ'ল এনএএন পাওয়া গেলে সঙ্গে সঙ্গে সত্যটি ফিরিয়ে দেওয়া:

import numba
import numpy as np

NAN = float("nan")

@numba.njit(nogil=True)
def _any_nans(a):
    for x in a:
        if np.isnan(x): return True
    return False

@numba.jit
def any_nans(a):
    if not a.dtype.kind=='f': return False
    return _any_nans(a.flat)

array1M = np.random.rand(1000000)
assert any_nans(array1M)==False
%timeit any_nans(array1M)  # 573us

array1M[0] = NAN
assert any_nans(array1M)==True
%timeit any_nans(array1M)  # 774ns  (!nanoseconds)

এবং n- মাত্রার জন্য কাজ করে:

array1M_nd = array1M.reshape((len(array1M)/2, 2))
assert any_nans(array1M_nd)==True
%timeit any_nans(array1M_nd)  # 774ns

এটিকে নকল দেশীয় সমাধানের সাথে তুলনা করুন:

def any_nans(a):
    if not a.dtype.kind=='f': return False
    return np.isnan(a).any()

array1M = np.random.rand(1000000)
assert any_nans(array1M)==False
%timeit any_nans(array1M)  # 456us

array1M[0] = NAN
assert any_nans(array1M)==True
%timeit any_nans(array1M)  # 470us

%timeit np.isnan(array1M).any()  # 532us

প্রারম্ভিক-প্রস্থান পদ্ধতি 3 টি অর্ডার বা মাত্রার গতিবেগ (কিছু ক্ষেত্রে)। সাধারণ টীকা দেওয়ার জন্য খুব জঞ্জাল নয়।


3

নপি 1.3 বা এসএনএন দিয়ে আপনি এটি করতে পারেন

In [1]: a = arange(10000.).reshape(100,100)

In [3]: isnan(a.max())
Out[3]: False

In [4]: a[50,50] = nan

In [5]: isnan(a.max())
Out[5]: True

In [6]: timeit isnan(a.max())
10000 loops, best of 3: 66.3 µs per loop

তুলনায় ন্যানের চিকিত্সা আগের সংস্করণগুলির সাথে সামঞ্জস্য ছিল না।


float('nan') in xকাজ না করার মতো কিছু কেন ? আমি চেষ্টা করেছিলাম এবং পাইথন Falseযেখানে ফিরে আসে x = [1,2,3,float('nan')]
চার্লি পার্কার

@ চর্লিপার্কার ... কারণ এনএএন এর সাথে তুলনা করা আপনার প্রত্যাশা মতো করে না। এনএএন-কে লজিক্যাল নুলের মতো আচরণ করা হয় (= জানেন না)। float("nan")==float("nan")দিন False(যদিও সম্ভবত এটি এনএএন বা কেউই ফেরেনি) একইভাবে এনএএন এবং বুলন নুলের সাথে বিজোড়তা এসকিউএল সহ অনেকগুলি ভাষায় সত্য (যেখানে এনইউএল = এনইউএল কখনও সত্য হয় না)।
ব্যবহারকারী 48956

2

(np.where(np.isnan(A)))[0].shape[0]বেশি হবে চেয়ে 0যদি Aঅন্তত এক উপাদান রয়েছে nan, Aএকটি হতে পারেn x m ম্যাট্রিক্স।

উদাহরণ:

import numpy as np

A = np.array([1,2,4,np.nan])

if (np.where(np.isnan(A)))[0].shape[0]: 
    print "A contains nan"
else:
    print "A does not contain nan"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.