নমপি অ্যারে নিকটতম মান সন্ধান করুন


336

কোন অ্যারের নিকটতম মানটি খুঁজে পেতে কোনও ন্যালি-থোনিক উপায় আছে, যেমন ফাংশন ?

উদাহরণ:

np.find_nearest( array, value )

উত্তর:


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

array = np.random.random(10)
print(array)
# [ 0.21069679  0.61290182  0.63425412  0.84635244  0.91599191  0.00213826
#   0.17104965  0.56874386  0.57319379  0.28719469]

value = 0.5

print(find_nearest(array, value))
# 0.568743859261

52
@ ইওল: return np.abs(array-value).min()ভুল উত্তর দেয়। এটি আপনাকে পরম মানের দূরত্বের মিনিট দেয় এবং কোনওভাবে আমাদের আসল অ্যারের মানটি ফেরত দিতে হবে। আমরা যোগ করতে valueএবং কাছে আসতে পারতাম , তবে পরম মানটি জিনিসগুলিতে একটি রেঞ্চ ফেলে দেয় ...
আনটবু

9
@ ~ আনতুবু আপনি ঠিক বলেছেন, আমার খারাপ। আমি আপনার সমাধানের চেয়ে ভাল কিছু ভাবতে পারি না!
এরিক হে লেবিগোট

24
উন্মাদ বলে মনে হচ্ছে একটি বিল্ট-ইন বিল্ট-ইন নেই যা এটি করে।
dbliss

3
@jsmedmar দ্বিখণ্ডিত পদ্ধতিটি (আমার নীচের উত্তরটি দেখুন) ও (লগ (এন))।
জোশ আলবার্ট

4
FutureWarning: 'argmin' is deprecated. Use 'idxmin' instead. The behavior of 'argmin' will be corrected to return the positional minimum in the future. Use 'series.values.argmin' to get the position of the minimum now.idxminপরিবর্তে ব্যবহার করে argminউপরের সমাধানটি আমার সাথে কাজ করে। (v3.6.4)
জোরিজনসিত 15'18

78

যদি আপনার অ্যারে বাছাই করা হয় এবং খুব বড় হয় তবে এটি আরও দ্রুত সমাধান:

def find_nearest(array,value):
    idx = np.searchsorted(array, value, side="left")
    if idx > 0 and (idx == len(array) or math.fabs(value - array[idx-1]) < math.fabs(value - array[idx])):
        return array[idx-1]
    else:
        return array[idx]

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


এটি সবচেয়ে যুক্তিসঙ্গত সমাধান বলে মনে হচ্ছে। আমি ভাবছি কেন এটি এত ধীর হয়। সমতল np.searchsortedআমার পরীক্ষার সেটটির জন্য প্রায় 2 µ সে সময় নেয়, পুরো ফাংশনটি প্রায় 10। Μ np.absএটি আরও খারাপ হচ্ছে ব্যবহার করে। অজগর সেখানে কী করছে সে সম্পর্কে কোনও ধারণা নেই।
মাইকেল

2
@ মিশেল একক মানগুলির জন্য, নম্পি গণিতের রুটিনগুলি mathরুটিনের চেয়ে ধীর হবে , এই উত্তরটি দেখুন
দিমিত্রি

3
আপনি একবারে (কয়েকটি সমন্বয় সহ) সন্ধান করতে চান এমন একাধিক মান থাকলে এটিই সেরা সমাধান। পুরো if/elseচাহিদার সঙ্গে প্রতিস্থাপন করাidx = idx - (np.abs(value - array[idx-1]) < np.abs(value - array[idx])); return array[idx]
coderforlife

3
এটি দুর্দান্ত তবে সবচেয়ে বড় উপাদানটির valueচেয়ে বড় হলে কাজ করে না array। আমি ifবিবৃতিটি if idx == len(array) or math.fabs(value - array[idx - 1]) < math.fabs(value - array[idx])এটির জন্য কার্যকর করে তুললাম!
নিকোকো

3
আইডিএক্স 0 হলে এটি কাজ করে না The যদি পড়তে হবে:if idx > 0 and (idx == len(array) or math.fabs(value - array[idx-1]) < math.fabs(value - array[idx])):
জেপেজেট

52

সামান্য সংশোধন করে, উপরের উত্তরটি সালিশি মাত্রার অ্যারে (1 ডি, 2 ডি, 3 ডি, ...) এর সাথে কাজ করে:

def find_nearest(a, a0):
    "Element in nd array `a` closest to the scalar value `a0`"
    idx = np.abs(a - a0).argmin()
    return a.flat[idx]

বা, একটি একক লাইন হিসাবে লিখিত:

a.flat[np.abs(a - a0).argmin()]

6
"ফ্ল্যাট" বিট প্রয়োজনীয় নয়। a[np.abs(a-a0).argmin)]ঠিকভাবে কাজ করে.
সর্বোচ্চ শ্রেন

2
আসলে, এটি এখনও কেবলমাত্র একটি মাত্রার জন্য কাজ করে, যেহেতু আরগমিন () কলাম / মাত্রা অনুসারে একাধিক ফলাফল দেয়। আমার একটা টাইপও ছিল এই কাজ করে অন্তত 2 মাত্রার জন্য: a[np.sum(np.square(np.abs(a-a0)),1).argmin()]
ম্যাক্স শ্রন

3
সুতরাং, এটি উচ্চ মাত্রার জন্য কাজ করে না, এবং উত্তরটি মুছে ফেলা উচিত (বা এটি প্রতিফলিত করতে সংশোধিত)
হিউজ ফোনটেনেল

11
প্রস্তাবিত উত্তর কোনও কাজ করে না এমন দয়া করে একটি উদাহরণ সরবরাহ করুন। যদি আপনি একটি খুঁজে পান তবে আমি আমার উত্তরটি পরিবর্তন করব। যদি আপনি একটি খুঁজে না পান তবে আপনি কি আপনার মন্তব্যগুলি সরাতে পারবেন?
kwgoodman

18

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

প্রথমে আপনার নিকটতম মানের দ্বারা কী বোঝানো উচিত তা পরিষ্কার করা উচিত । প্রায়শই কেউ একটি অ্যাবসিসায় ব্যবধান চান, যেমন অ্যারে = [0,0.7,2.1], মান = 1.95, উত্তর হবে আইডিএক্স = 1 = এটি আমার ক্ষেত্রে সন্দেহ হয় যে আপনার প্রয়োজন (অন্যথায় আপনি বিরতিটি শোনার পরে নিম্নলিখিতগুলি ফলোআপ শর্তাধীন বিবৃতি দিয়ে খুব সহজেই সংশোধন করা যেতে পারে)। আমি লক্ষ করব যে এটি করার সর্বোত্তম উপায়টি দ্বিখণ্ডনের সাথে রয়েছে (যা আমি প্রথমে সরবরাহ করব - নোট করুন এটি মোটেও নিষ্প্রয়োজনের প্রয়োজন হয় না এবং নির্লিপ্ত ক্রিয়াকলাপগুলি ব্যবহার করার চেয়ে দ্রুততর কারণ তারা অপ্রয়োজনীয় ক্রিয়াকলাপগুলি সম্পাদন করে)। তারপরে আমি অন্যান্য ব্যবহারকারীদের দ্বারা এখানে উপস্থাপন করা অন্যদের বিরুদ্ধে সময়সীমা তুলনা করব।

দ্বিখণ্ডন:

def bisection(array,value):
    '''Given an ``array`` , and given a ``value`` , returns an index j such that ``value`` is between array[j]
    and array[j+1]. ``array`` must be monotonic increasing. j=-1 or j=len(array) is returned
    to indicate that ``value`` is out of range below and above respectively.'''
    n = len(array)
    if (value < array[0]):
        return -1
    elif (value > array[n-1]):
        return n
    jl = 0# Initialize lower
    ju = n-1# and upper limits.
    while (ju-jl > 1):# If we are not yet done,
        jm=(ju+jl) >> 1# compute a midpoint with a bitshift
        if (value >= array[jm]):
            jl=jm# and replace either the lower limit
        else:
            ju=jm# or the upper limit, as appropriate.
        # Repeat until the test condition is satisfied.
    if (value == array[0]):# edge cases at bottom
        return 0
    elif (value == array[n-1]):# and top
        return n-1
    else:
        return jl

এখন আমি অন্যান্য উত্তরগুলি থেকে কোডটি সংজ্ঞায়িত করব, তারা প্রত্যেকে একটি সূচক ফেরত দেয়:

import math
import numpy as np

def find_nearest1(array,value):
    idx,val = min(enumerate(array), key=lambda x: abs(x[1]-value))
    return idx

def find_nearest2(array, values):
    indices = np.abs(np.subtract.outer(array, values)).argmin(0)
    return indices

def find_nearest3(array, values):
    values = np.atleast_1d(values)
    indices = np.abs(np.int64(np.subtract.outer(array, values))).argmin(0)
    out = array[indices]
    return indices

def find_nearest4(array,value):
    idx = (np.abs(array-value)).argmin()
    return idx


def find_nearest5(array, value):
    idx_sorted = np.argsort(array)
    sorted_array = np.array(array[idx_sorted])
    idx = np.searchsorted(sorted_array, value, side="left")
    if idx >= len(array):
        idx_nearest = idx_sorted[len(array)-1]
    elif idx == 0:
        idx_nearest = idx_sorted[0]
    else:
        if abs(value - sorted_array[idx-1]) < abs(value - sorted_array[idx]):
            idx_nearest = idx_sorted[idx-1]
        else:
            idx_nearest = idx_sorted[idx]
    return idx_nearest

def find_nearest6(array,value):
    xi = np.argmin(np.abs(np.ceil(array[None].T - value)),axis=0)
    return xi

এখন আমি কোডগুলি সময় করব: নোট পদ্ধতিগুলি 1,2,4,5 সঠিকভাবে অন্তর দেয় না। পদ্ধতিগুলি অ্যারের নিকটস্থ বিন্দুতে 1,2,4 টি বৃত্তাকার (যেমন> = 1.5 -> 2), এবং পদ্ধতি 5 সর্বদা রাউন্ড আপ হয় (যেমন 1.45 -> 2)। কেবলমাত্র 3 এবং 6 পদ্ধতি এবং অবশ্যই দ্বিখণ্ডিতভাবে ব্যবধানটি সঠিকভাবে দেয়।

array = np.arange(100000)
val = array[50000]+0.55
print( bisection(array,val))
%timeit bisection(array,val)
print( find_nearest1(array,val))
%timeit find_nearest1(array,val)
print( find_nearest2(array,val))
%timeit find_nearest2(array,val)
print( find_nearest3(array,val))
%timeit find_nearest3(array,val)
print( find_nearest4(array,val))
%timeit find_nearest4(array,val)
print( find_nearest5(array,val))
%timeit find_nearest5(array,val)
print( find_nearest6(array,val))
%timeit find_nearest6(array,val)

(50000, 50000)
100000 loops, best of 3: 4.4 µs per loop
50001
1 loop, best of 3: 180 ms per loop
50001
1000 loops, best of 3: 267 µs per loop
[50000]
1000 loops, best of 3: 390 µs per loop
50001
1000 loops, best of 3: 259 µs per loop
50001
1000 loops, best of 3: 1.21 ms per loop
[50000]
1000 loops, best of 3: 746 µs per loop

একটি বৃহত অ্যারে দ্বিপক্ষীয় পরবর্তী সেরা 180us এবং দীর্ঘতম 1.21 মিমি (~ 100 - 1000 গুণ দ্রুত) এর তুলনায় 4us দেয়। ছোট অ্যারেগুলির জন্য এটি 2-100 গুন দ্রুত।


2
আপনি ধরে নিচ্ছেন যে অ্যারে বাছাই করা হয়েছে। কেউ অ্যারে বাছাই করতে না চাওয়ার অনেকগুলি কারণ রয়েছে: উদাহরণস্বরূপ, অ্যারে যদি একটি লাইন গ্রাফের ডেটা পয়েন্টগুলি উপস্থাপন করে।
ব্যবহারকারী 1917407

7
পাইথন স্ট্যান্ডার্ড লাইব্রেরিতে ইতিমধ্যে দ্বিখণ্ডিত
ফেলিক্স

আপনি যখন বলেছিলেন, "যদি arrayছোট হয় তবে পদ্ধতি 2টিকে সবচেয়ে দ্রুত বলে মনে হয়।" আপনি @ জোশআলবার্ট বলতে কতটা ছোট?
মিঃ জিউস

2
এটি নিকটতম মানটি খুঁজে পায় না, এটি পরবর্তী সর্বনিম্ন মানটি সন্ধান করে।
এন্ডোলিথ

@endolith এটি কেবল দ্বিখণ্ডনের ক্ষেত্রে।
হোমরো

17

ভেক্টরগুলির একটি অ্যারে নিকটতম ভেক্টরটি সন্ধানের জন্য এখানে একটি বর্ধিতকরণ রয়েছে।

import numpy as np

def find_nearest_vector(array, value):
  idx = np.array([np.linalg.norm(x+y) for (x,y) in array-value]).argmin()
  return array[idx]

A = np.random.random((10,2))*100
""" A = array([[ 34.19762933,  43.14534123],
   [ 48.79558706,  47.79243283],
   [ 38.42774411,  84.87155478],
   [ 63.64371943,  50.7722317 ],
   [ 73.56362857,  27.87895698],
   [ 96.67790593,  77.76150486],
   [ 68.86202147,  21.38735169],
   [  5.21796467,  59.17051276],
   [ 82.92389467,  99.90387851],
   [  6.76626539,  30.50661753]])"""
pt = [6, 30]  
print find_nearest_vector(A,pt)
# array([  6.76626539,  30.50661753])

আমি মনে করি পাইথন পুনরাবৃত্তির মাধ্যমে মানগুলি norm(..., axis=-1)বের করার চেয়ে দ্রুত হওয়া উচিত x,y। এছাড়াও, x,yস্কেলারগুলি এখানে রয়েছে? তারপরে norm(x+y)একটি বাগ রয়েছে, উদাহরণস্বরূপ, দূরত্বটি (+1, -1)0 হিসাবে গণ্য হবে
এফএইচএফ

এটি আমার জন্য কাজ করেছিলidx = np.array([np.linalg.norm(x+y) for (x,y) in abs(array-value)]).argmin()
ezchx

9

আপনি যদি নাম্পি ব্যবহার করতে না চান তবে এটি এটি করবে:

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

9

এখানে এমন একটি সংস্করণ যা একটি স্কেলারবিহীন "মান" অ্যারে পরিচালনা করবে:

import numpy as np

def find_nearest(array, values):
    indices = np.abs(np.subtract.outer(array, values)).argmin(0)
    return array[indices]

অথবা ইনপুটটি যদি স্কেলার হয় তবে এমন একটি সংস্করণ যা কোনও সংখ্যার প্রকার (যেমন ইনট, ফ্লোট) ফেরত দেয়:

def find_nearest(array, values):
    values = np.atleast_1d(values)
    indices = np.abs(np.subtract.outer(array, values)).argmin(0)
    out = array[indices]
    return out if len(out) > 1 else out[0]

উত্তম উত্তর, আমি আগে কখনও outerইউফুঙ্কের পদ্ধতিটি ব্যবহার করি নি, আমি মনে করি ভবিষ্যতে আরও ব্যবহার করব। প্রথম ফাংশনটি array[indices]উপায় দ্বারা ফিরে আসা উচিত ।
উইডজেট

1
এই সমাধানটি স্কেল করে না। np.subtract.outerপুরো আউট-প্রোডাক্ট ম্যাট্রিক্স তৈরি করবে যা সত্যিই ধীর এবং মেমরি নিবিড় যদি arrayএবং / অথবা valuesখুব বড় হয়।
অ্যান্টনিবেল

8

এখানে @Ari Onasafari, উত্তরের জন্য scipy সঙ্গে একটি সংস্করণ " ভেক্টর একটি অ্যারের মধ্যে নিকটতম ভেক্টর এটি "

In [1]: from scipy import spatial

In [2]: import numpy as np

In [3]: A = np.random.random((10,2))*100

In [4]: A
Out[4]:
array([[ 68.83402637,  38.07632221],
       [ 76.84704074,  24.9395109 ],
       [ 16.26715795,  98.52763827],
       [ 70.99411985,  67.31740151],
       [ 71.72452181,  24.13516764],
       [ 17.22707611,  20.65425362],
       [ 43.85122458,  21.50624882],
       [ 76.71987125,  44.95031274],
       [ 63.77341073,  78.87417774],
       [  8.45828909,  30.18426696]])

In [5]: pt = [6, 30]  # <-- the point to find

In [6]: A[spatial.KDTree(A).query(pt)[1]] # <-- the nearest point 
Out[6]: array([  8.45828909,  30.18426696])

#how it works!
In [7]: distance,index = spatial.KDTree(A).query(pt)

In [8]: distance # <-- The distances to the nearest neighbors
Out[8]: 2.4651855048258393

In [9]: index # <-- The locations of the neighbors
Out[9]: 9

#then 
In [10]: A[index]
Out[10]: array([  8.45828909,  30.18426696])

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

8

@ দিমিত্রি এর সমাধানের একটি দ্রুত ভেক্টরাইজড সংস্করণ এখানে যদি আপনার valuesসন্ধানের জন্য অনেকগুলি থাকে ( valuesবহুমাত্রিক অ্যারে হতে পারে):

#`values` should be sorted
def get_closest(array, values):
    #make sure array is a numpy array
    array = np.array(array)

    # get insert positions
    idxs = np.searchsorted(array, values, side="left")

    # find indexes where previous index is closer
    prev_idx_is_less = ((idxs == len(array))|(np.fabs(values - array[np.maximum(idxs-1, 0)]) < np.fabs(values - array[np.minimum(idxs, len(array)-1)])))
    idxs[prev_idx_is_less] -= 1

    return array[idxs]

benchmarks

> for@ ডেমিট্রির সমাধান` দিয়ে একটি লুপ ব্যবহারের চেয়ে 100 গুণ বেশি দ্রুত `

>>> %timeit ar=get_closest(np.linspace(1, 1000, 100), np.random.randint(0, 1050, (1000, 1000)))
139 ms ± 4.04 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

>>> %timeit ar=[find_nearest(np.linspace(1, 1000, 100), value) for value in np.random.randint(0, 1050, 1000*1000)]
took 21.4 seconds

অ্যারেতে আপনার যদি ধ্রুবক নমুনা থাকে তবে তা আরও সহজ হয়ে যায়: idx = np.searchsorted(array, values)তারপরে idx[array[idx] - values>np.diff(array).mean()*0.5]-=1এবং অবশেষেreturn array[idx]
সের্গেই আন্তোপলস্কি

7

বড় অ্যারেগুলির জন্য, @ দিমিত্রি প্রদত্ত (দুর্দান্ত) উত্তরটি বর্তমানে সেরা হিসাবে চিহ্নিত হিসাবে উত্তরের চেয়ে অনেক দ্রুত। আমি তার সঠিক অ্যালগরিদম নিম্নলিখিত দুটি উপায়ে মানিয়ে নিয়েছি:

  1. ইনপুট অ্যারে বাছাই করা আছে কিনা নীচের ফাংশনটি কাজ করে।

  2. নীচের ফাংশনটি নিকটতম মান অনুসারে ইনপুট অ্যারের সূচকটি প্রদান করে যা কিছুটা সাধারণ।

নোট করুন যে নীচের ফাংশনটি একটি নির্দিষ্ট প্রান্ত কেস পরিচালনা করে যা @ ডিমেট্রি দ্বারা লিখিত মূল ফাংশনে একটি বাগ তৈরি করতে পারে। অন্যথায়, আমার অ্যালগরিদম তার অনুরূপ।

def find_idx_nearest_val(array, value):
    idx_sorted = np.argsort(array)
    sorted_array = np.array(array[idx_sorted])
    idx = np.searchsorted(sorted_array, value, side="left")
    if idx >= len(array):
        idx_nearest = idx_sorted[len(array)-1]
    elif idx == 0:
        idx_nearest = idx_sorted[0]
    else:
        if abs(value - sorted_array[idx-1]) < abs(value - sorted_array[idx]):
            idx_nearest = idx_sorted[idx-1]
        else:
            idx_nearest = idx_sorted[idx]
    return idx_nearest

1
এটি উল্লেখ করার মতো যে এটি কীভাবে অনুকূলিতকরণ কোডটিকে আরও খারাপ এবং আরও শক্ত করে তুলতে ঝোঁক তার একটি দুর্দান্ত উদাহরণ এটি worth @ ইউনটবু প্রদত্ত উত্তরটি এমন ক্ষেত্রে (অনেক বেশি) পছন্দ করা উচিত যেখানে গতি বড় উদ্বেগ নয়, যেহেতু এটি আরও স্বচ্ছ।
এপি

@ মিচেলের দেওয়া উত্তর আমি দেখতে পাচ্ছি না। এটা কি ত্রুটি নাকি আমি অন্ধ?
ফুকাচছু

নাহ, আপনি অন্ধ নন, আমি কেবল নিরক্ষর ;-) এটিই ছিল @ দিমিত্রি, যার উত্তর আমি প্রকাশ করছি। আমার খারাপ। আমি সবেমাত্র আমার পোস্ট স্থির করেছি। ধন্যবাদ!
এপি

আমি দিমিত্রি এবং আপনার সাথে বিভিন্ন উত্তর পেয়েছি। কোন ধারনা? x = np.array([2038, 1758, 1721, 1637, 2097, 2047, 2205, 1787, 2287, 1940, 2311, 2054, 2406, 1471, 1460])। সঙ্গে find_nearest(x, 1739.5)(প্রথম সমাংশক নিকটস্থ মান), আমি পেতে 1637(যুক্তিসঙ্গত) এবং 1(বাগ?)।
প্যাট্রিকটি

3

এটি আনটবুর উত্তরের একটি ভেক্টরাইজড সংস্করণ :

def find_nearest(array, values):
    array = np.asarray(array)

    # the last dim must be 1 to broadcast in (array - values) below.
    values = np.expand_dims(values, axis=-1) 

    indices = np.abs(array - values).argmin(axis=-1)

    return array[indices]


image = plt.imread('example_3_band_image.jpg')

print(image.shape) # should be (nrows, ncols, 3)

quantiles = np.linspace(0, 255, num=2 ** 2, dtype=np.uint8)

quantiled_image = find_nearest(quantiles, image)

print(quantiled_image.shape) # should be (nrows, ncols, 3)

2

আমি মনে করি সবচেয়ে পাইথোনিক উপায়টি হ'ল:

 num = 65 # Input number
 array = n.random.random((10))*100 # Given array 
 nearest_idx = n.where(abs(array-num)==abs(array-num).min())[0] # If you want the index of the element of array (array) nearest to the the given number (num)
 nearest_val = array[abs(array-num)==abs(array-num).min()] # If you directly want the element of array (array) nearest to the given number (num)

এটি মৌলিক কোড। আপনি চাইলে এটি একটি ফাংশন হিসাবে ব্যবহার করতে পারেন


2

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

import numpy as np
import bisect
xarr = np.random.rand(int(1e7))

srt_ind = xarr.argsort()
xar = xarr.copy()[srt_ind]
xlist = xar.tolist()
bisect.bisect_left(xlist, 0.3)

[]৩]:% সময় বিসেক্ট.বিসেক্ট_সামগ্রী (এক্সলিস্ট, ০.০) সিপিইউ বার: ব্যবহারকারী 0 এনএস, সিএস: 0 এনএস, মোট: 0 এনএস ওয়াল সময়: 22.2 µ সে

np.searchsorted(xar, 0.3, side="left")

[]৪] ইন:% সময় এনপি.সর্চসোর্টড (xar, 0.3, পাশ = "বাম") সিপিইউ বার: ব্যবহারকারী 0 এনএস, সিএস: 0 এনএস, মোট: 0 এনএস ওয়াল সময়: 98.9 µ সে

randpts = np.random.rand(1000)
np.searchsorted(xar, randpts, side="left")

% টাইম এনপি.সার্চসোর্টড (এক্সার, র্যান্ডপেটস, সাইড = "বাম") সিপিইউ বার: ব্যবহারকারী 4 এমএস, সিএস: 0 এনএস, মোট: 4 এমএস ওয়াল টাইম: 1.2 এমএস

আমরা যদি গুণক নিয়মটি অনুসরণ করি, তবে নিম্পিকে ~ 100 এমএস নেওয়া উচিত যা ~ 83X দ্রুত বোঝায়।


1

2 ডি অ্যারের জন্য, নিকটতম উপাদানটির i, j অবস্থান নির্ধারণ করতে:

import numpy as np
def find_nearest(a, a0):
    idx = (np.abs(a - a0)).argmin()
    w = a.shape[1]
    i = idx // w
    j = idx - i * w
    return a[i,j], i, j

0
import numpy as np
def find_nearest(array, value):
    array = np.array(array)
    z=np.abs(array-value)
    y= np.where(z == z.min())
    m=np.array(y)
    x=m[0,0]
    y=m[1,0]
    near_value=array[x,y]

    return near_value

array =np.array([[60,200,30],[3,30,50],[20,1,-50],[20,-500,11]])
print(array)
value = 0
print(find_nearest(array, value))

1
হাই, স্ট্যাক ওভারফ্লোতে আপনাকে স্বাগতম কীভাবে একটি ভাল উত্তর লিখতে হয় তা পরীক্ষা করে দেখুন । প্রশ্নের প্রসঙ্গে আপনি কী করেছিলেন তার একটি সংক্ষিপ্ত বিবরণ দেওয়ার চেষ্টা করুন!
ট্রিস্টো

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