اذهب إلى المحتوى

السؤال

نشر

هل هناك طريقة أو دالة في Numpy لإيجاد أقرب قيمة في المصفوفة؟

على سبيل المثال، لدي مصفوفة كالتالي:

>>> import numpy as np
>>> array = np.random.random(10)
>>> array
array([0.98547232, 0.72307097, 0.74612579, 0.92416426, 0.56989436,
       0.44332925, 0.76635451, 0.54613872, 0.42633231, 0.72585823])

أريد دالة تعطيني أقرب قيمة في المصفوفة لرقم معين كالتالي:

get_nearest(array, 5.0)	# Output: 0.54613872

 

Recommended Posts

  • 1
نشر (معدل)

يمكنك استخدام التابع التالي، حيث نعتمد على فكرة طرح القيمة المطلوبة من كل عنصر في المصفوفة، وبالتالي تتشكل لدينا مصفوفة الفرق بالقيمة المطلقة، ثم نستخدم التابع argmin ليعطينا موقع أصغر عنصر، ثم نستخدم flat لتعطينا القيمة الموافقة للموقع:

import numpy as np
array = np.random.random(10)
print(array)
"""
[0.59588654 0.43663869 0.49730145 0.65410536 0.98261646 0.06100155
 0.28296143 0.94809249 0.43775789 0.2167913 ]
"""
def find1(a, a0):
    index = np.abs(a - a0)
    print(idx)
    """
    [0.10411346 0.26336131 0.20269855 0.04589464 0.28261646 0.63899845
     0.41703857 0.24809249 0.26224211 0.4832087 ]
    """
    index=idx.argmin()
    print(index) # 3
    print(a.flat[index]) # 0.6541053630832852
    return a.flat[index]
find1(array,0.7) # 0.6541053630832852

الآن سأكتب التابع بشكل مختصر:

import numpy as np
array = np.random.random(10)
def find1(a, a0):
    index = np.abs(a - a0).argmin()
    return a.flat[index]
find1(array,0.7)

أو يمكنك استخدام الطريقة التالية وهي مشابهة إلى حد كبير بالطريقة الأولى (بالشكل والسرعة):

import numpy as np
#array = np.random.random(10)
print(array)
"""
[0.59588654 0.43663869 0.49730145 0.65410536 0.98261646 0.06100155
 0.28296143 0.94809249 0.43775789 0.2167913 ]
"""
def find2(a, values):
    index = np.abs(np.subtract.outer(array, values)).argmin(0)
    return a.flat[index]
find2(array,0.7) # 0.6541053630832852

أو بالطريقة التالية حيث نعتمد على ترتيب المصفوفة أولاً وهي عموماً لاتحتاج لاستخدام نمباي معها، وهي تأخذ المصفوفة المراد البحث فيها والقيمة التي نبحث عن أقرب قيمة لها وترد لنا الموقع الموجودة فيه، ويتم إرجاع -1 أو طول المصفوفة للإشارة إلى أن القيمة خارج النطاق أدناه وأعلى بالترتيب:

import numpy as np
array = np.random.random(10)
print(array)
def bi(a,val):
    a=np.sort(a)
    """
    [0.06100155 0.2167913  0.28296143 0.43663869 0.43775789 0.49730145
     0.59588654 0.65410536 0.94809249 0.98261646]
    """
    n = len(a)
    if (val < a[0]):
        return -1
    elif (val > a[n-1]):
        return n
    jl = 0 # تهيئة أقل حد 
    ju = n-1 # الأعلى
    # طالما لم يتحقق الشرط التالي
    # نكرر حتى يتحقق الشرط
    while (ju-jl > 1):
        jm=(ju+jl) >> 1 # احسب القيمة في المنتصف مع إزاحة 
        if (val >= array[jm]):
            jl=jm # واستبدل إما الحد الأدنى
        else:
            ju=jm # أو الأعلى        
    if (val == a[0]):
        return 0
    elif (val == a[n-1]):
        return n-1
    else:
        return jl

bisection(array,0.7) # 0.6541053630832852

الآن سأجري مقارنة بينهم:

import numpy as np
def bi(array,value):
    array=np.sort(array)
    n = len(array)
    if (value < array[0]):
        return -1
    elif (value > array[n-1]):
        return n
    jl = 0
    ju = n-1
    while (ju-jl > 1):
        jm=(ju+jl) >> 1
        if (value >= array[jm]):
            jl=jm
        else:
            ju=jm        
    if (value == array[0]):
        return 0
    elif (value == array[n-1]):
        return n-1
    else:
        return jl
def find1(a, a0):
    index = np.abs(a - a0).argmin()
    return index
def find2(a, values):
    index = np.abs(np.subtract.outer(array, values)).argmin(0)
    return index
# المقارنة
array = np.random.random(1000)
%timeit bi(array,0.7)
print(bisection(array,0.7))
%timeit find1(array,0.7)
print(find1(array,0.7))
%timeit find2(array,0.7)
print(find2(array,0.7))
"""
535 ns ± 19.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
-1
5.92 µs ± 1.02 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)
537
6.37 µs ± 336 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
537
"""

 

تم التعديل في بواسطة Ali Haidar Ahmad
  • 0
نشر

يمكنك استخدام الدالة التالية

import numpy as np
def get_nearest(array, value):
    array = np.asarray(array)
    idx = (np.abs(array - value)).argmin()
    return array[idx]

لنفترض لدينا هذه المصفوفة

>>> array = np.random.random(10)
>>> array
array([0.98547232, 0.72307097, 0.74612579, 0.92416426, 0.56989436,
       0.44332925, 0.76635451, 0.54613872, 0.42633231, 0.72585823])

وعلى فرض أن قيمة المعامل الثاني هي 0.5 فسوف يكون استدعاء الدالة كالتالي

get_nearest(array, 5.0)

وسوف تكون النتيجة كالتالي

0.54613872

 

  • 0
نشر

لا توجد دالة خاصة بتنفيذ ما تريده إنما يمكنك تنقيذ ذلك من خلال بعض الدوال 

و إذا كنت تريد استخدام ال loop يمكنك استخدام الحل التالي

def find_nearest(array, value):
    n = [abs(i-value) for i in array]
    idx = n.index(min(n))
    return array[idx]

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...