Numpy: सीमा के भीतर तत्वों का सूचकांक खोजें


85

उदाहरण के लिए मेरे पास संख्याओं की एक सरणी है,

a = np.array([1, 3, 5, 6, 9, 10, 14, 15, 56])  

मैं तत्वों के सभी अनुक्रमों को एक विशिष्ट सीमा के भीतर खोजना चाहूंगा। उदाहरण के लिए, यदि श्रेणी (6, 10) है, तो उत्तर (3, 4, 5) होना चाहिए। क्या ऐसा करने के लिए एक अंतर्निहित फ़ंक्शन है?

जवाबों:


140

आप np.whereसूचकांक प्राप्त np.logical_andकरने और दो स्थितियाँ निर्धारित करने के लिए उपयोग कर सकते हैं:

import numpy as np
a = np.array([1, 3, 5, 6, 9, 10, 14, 15, 56])

np.where(np.logical_and(a>=6, a<=10))
# returns (array([3, 4, 5]),)

6
Btw, एक ही द्वारा हासिल की है np.nonzero(np.logical_and(a>=6, a<=10))
3lectrologos

10
इसके अलावा np.where((a > 6) & (a <= 10))
एलिंडा

बहुआयामी सरणियों के साथ अच्छी तरह से करने के लिए प्रतीत नहीं होता है
मोनिका हेडडेक

1
@ELinda np.logical_andएक बालक है, &हालांकि तेजी से । और np.whereसे तेज है np.nonzero
Skillmon

बड़े सरणियों के लिए इसका बहुत बुरा प्रदर्शन है
EZLearner

62

@ Deinonychusaur के उत्तर के रूप में, लेकिन इससे भी अधिक कॉम्पैक्ट:

In [7]: np.where((a >= 6) & (a <=10))
Out[7]: (array([3, 4, 5]),)

19
अच्छा लगा। आप भी कर सकते हैं a[(a >= 6) & (a <= 10)]अगर aएक संख्यात्मक सरणी है।
ws_e_c421

1
जैसे ही कोई व्यक्ति भ्रमित हो जाता है जैसे मैंने टिप्पणी के शब्दों के साथ किया था: यह सामान्य सूचियों के लिए काम नहीं करता है, यह केवल तभी aहै जब एक सुस्पष्ट सरणी है
प्रोफेसर

14

मैंने सोचा था कि मैं इसे जोड़ दूंगा क्योंकि aआपके द्वारा दिए गए उदाहरण में हल है:

import numpy as np
a = [1, 3, 5, 6, 9, 10, 14, 15, 56] 
start = np.searchsorted(a, 6, 'left')
end = np.searchsorted(a, 10, 'right')
rng = np.arange(start, end)
rng
# array([3, 4, 5])


6

उत्तरों का सारांश

यह समझने के लिए कि सबसे अच्छा उत्तर क्या है, हम अलग-अलग समाधान का उपयोग करके कुछ समय दे सकते हैं। दुर्भाग्य से, प्रश्न अच्छी तरह से प्रस्तुत नहीं किया गया था इसलिए विभिन्न प्रश्नों के उत्तर हैं, यहां मैं उसी प्रश्न के उत्तर को इंगित करने का प्रयास करता हूं। सरणी को देखते हुए:

a = np.array([1, 3, 5, 6, 9, 10, 14, 15, 56])

उत्तर एक निश्चित सीमा के बीच तत्वों का अनुक्रमित होना चाहिए , हम समावेशी मानते हैं, इस मामले में, 6 और 10।

answer = (3, 4, 5)

6,9,10 के मूल्यों के अनुरूप।

सर्वश्रेष्ठ उत्तर का परीक्षण करने के लिए हम इस कोड का उपयोग कर सकते हैं।

import timeit
setup = """
import numpy as np
import numexpr as ne

a = np.array([1, 3, 5, 6, 9, 10, 14, 15, 56])
# we define the left and right limit
ll = 6
rl = 10

def sorted_slice(a,l,r):
    start = np.searchsorted(a, l, 'left')
    end = np.searchsorted(a, r, 'right')
    return np.arange(start,end)
"""

functions = ['sorted_slice(a,ll,rl)', # works only for sorted values
'np.where(np.logical_and(a>=ll, a<=rl))[0]',
'np.where((a >= ll) & (a <=rl))[0]',
'np.where((a>=ll)*(a<=rl))[0]',
'np.where(np.vectorize(lambda x: ll <= x <= rl)(a))[0]',
'np.argwhere((a>=ll) & (a<=rl)).T[0]', # we traspose for getting a single row
'np.where(ne.evaluate("(ll <= a) & (a <= rl)"))[0]',]

functions2 = [
   'a[np.logical_and(a>=ll, a<=rl)]',
   'a[(a>=ll) & (a<=rl)]',
   'a[(a>=ll)*(a<=rl)]',
   'a[np.vectorize(lambda x: ll <= x <= rl)(a)]',
   'a[ne.evaluate("(ll <= a) & (a <= rl)")]',
]

परिणाम

परिणाम निम्नलिखित साजिश में बताए गए हैं। शीर्ष पर सबसे तेज़ समाधान। यहाँ छवि विवरण दर्ज करें यदि आप अनुक्रमित के बजाय मानों को निकालना चाहते हैं, तो आप फ़ंक्शन 2 का उपयोग करके परीक्षण कर सकते हैं, लेकिन परिणाम लगभग समान हैं।


ये परिणाम केवल एक विशिष्ट-लंबाई सरणी के लिए लागू होते हैं (यहां आपने बहुत छोटा सरणी चुना है)। इन परिणामों को बड़ी सरणियों के लिए तेजी से बदल दिया जाता है
EZLearner

4

यह कोड स्निपेट सभी मानों को दो मानों के बीच एक संख्या में देता है:

a = np.array([1, 3, 5, 6, 9, 10, 14, 15, 56] )
a[(a>6)*(a<10)]

यह निम्नलिखित के रूप में काम करता है: (ए> 6) ट्रू (1) और गलत (0) के साथ एक संख्यात्मक सरणी देता है, इसलिए ऐसा करता है (एक <10)। इन दोनों को एक साथ गुणा करने से आपको या तो ट्रू के साथ एक सरणी मिलती है, यदि दोनों स्टेटमेंट ट्रू हैं (क्योंकि 1x1 = 1) या गलत (क्योंकि 0x0 = 0 और 1x0 = 0)।

भाग [...] सरणी के सभी मानों को लौटाता है जहाँ कोष्ठक के बीच का सरणी एक सही कथन देता है।

बेशक आप उदाहरण के लिए कहकर इसे और अधिक जटिल बना सकते हैं

...*(1-a<10) 

जो "और न" कथन के समान है।



1

जोड़ना चाहते थे numexpr मिश्रण में:

import numpy as np
import numexpr as ne

a = np.array([1, 3, 5, 6, 9, 10, 14, 15, 56])  

np.where(ne.evaluate("(6 <= a) & (a <= 10)"))[0]
# array([3, 4, 5], dtype=int64)

केवल लाखों के साथ बड़े सरणियों के लिए समझ में आता है ... या यदि आप एक स्मृति सीमा मार रहे हैं।


1

अन्य तरीका है:

np.vectorize(lambda x: 6 <= x <= 10)(a)

कौन सा रिटर्न:

array([False, False, False,  True,  True,  True, False, False, False])

यह कभी-कभी टाइम सीरीज़, वैक्टर आदि के लिए उपयोगी होता है।


0
s=[52, 33, 70, 39, 57, 59, 7, 2, 46, 69, 11, 74, 58, 60, 63, 43, 75, 92, 65, 19, 1, 79, 22, 38, 26, 3, 66, 88, 9, 15, 28, 44, 67, 87, 21, 49, 85, 32, 89, 77, 47, 93, 35, 12, 73, 76, 50, 45, 5, 29, 97, 94, 95, 56, 48, 71, 54, 55, 51, 23, 84, 80, 62, 30, 13, 34]

dic={}

for i in range(0,len(s),10):
    dic[i,i+10]=list(filter(lambda x:((x>=i)&(x<i+10)),s))
print(dic)

for keys,values in dic.items():
    print(keys)
    print(values)

आउटपुट:

(0, 10)
[7, 2, 1, 3, 9, 5]
(20, 30)
[22, 26, 28, 21, 29, 23]
(30, 40)
[33, 39, 38, 32, 35, 30, 34]
(10, 20)
[11, 19, 15, 12, 13]
(40, 50)
[46, 43, 44, 49, 47, 45, 48]
(60, 70)
[69, 60, 63, 65, 66, 67, 62]
(50, 60)
[52, 57, 59, 58, 50, 56, 54, 55, 51]  

0

यह सबसे सुंदर नहीं हो सकता है, लेकिन किसी भी आयाम के लिए काम करता है

a = np.array([[-1,2], [1,5], [6,7], [5,2], [3,4], [0, 0], [-1,-1]])
ranges = (0,4), (0,4) 

def conditionRange(X : np.ndarray, ranges : list) -> np.ndarray:
    idx = set()
    for column, r in enumerate(ranges):
        tmp = np.where(np.logical_and(X[:, column] >= r[0], X[:, column] <= r[1]))[0]
        if idx:
            idx = idx & set(tmp)
        else:
            idx = set(tmp)
    idx = np.array(list(idx))
    return X[idx, :]

b = conditionRange(a, ranges)
print(b)

-4

आप इसे np.clip()प्राप्त करने के लिए उपयोग कर सकते हैं :

a = [1, 3, 5, 6, 9, 10, 14, 15, 56]  
np.clip(a,6,10)

हालाँकि, यह क्रमशः 6 और 10 से कम और अधिक मान रखता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.