मेरे पास एक संख्यात्मक सूची है:
myList = [1, 2, 3, 100, 5]
अब अगर मैं इस सूची को प्राप्त करने के लिए छाँटूँ [1, 2, 3, 5, 100]
। मैं जो चाहता हूं वह छांटे गए क्रम में मूल सूची से तत्वों [0, 1, 2, 4, 3]
का सूचकांक है।
मेरे पास एक संख्यात्मक सूची है:
myList = [1, 2, 3, 100, 5]
अब अगर मैं इस सूची को प्राप्त करने के लिए छाँटूँ [1, 2, 3, 5, 100]
। मैं जो चाहता हूं वह छांटे गए क्रम में मूल सूची से तत्वों [0, 1, 2, 4, 3]
का सूचकांक है।
जवाबों:
यदि आप numpy का उपयोग कर रहे हैं, तो आपके पास argsort () फ़ंक्शन उपलब्ध है:
>>> import numpy
>>> numpy.argsort(myList)
array([0, 1, 2, 4, 3])
http://docs.scipy.org/doc/numpy/reference/generated/numpy.argsort.html
यह उन तर्कों को लौटाता है जो सरणी या सूची को क्रमबद्ध करेंगे।
आगे कुछ इस तरह:
>>> myList = [1, 2, 3, 100, 5]
>>> [i[0] for i in sorted(enumerate(myList), key=lambda x:x[1])]
[0, 1, 2, 4, 3]
enumerate(myList)
आपको एक सूची देता है जिसमें (इंडेक्स, वैल्यू) के tuples होते हैं:
[(0, 1), (1, 2), (2, 3), (3, 100), (4, 5)]
आप सूची को पास sorted
करके सॉर्ट कुंजी को निकालने के लिए किसी फ़ंक्शन को निर्दिष्ट करते हैं (प्रत्येक ट्यूपर का दूसरा तत्व)। यह है कि इसके lambda
लिए क्या है। अंत में, सूची क्रम का उपयोग करके प्रत्येक सॉर्ट किए गए तत्व का मूल सूचकांक निकाला जाता है [i[0] for i in ...]
।
itemgetter(1)
लैम्बडा फंक्शन के बजाय उपयोग कर सकते हैं
itemgetter
में फ़ंक्शन का उल्लेख कर रहा है operator
, FYI करें। इसलिए from operator import itemgetter
इसका इस्तेमाल जरूर करें।
sorted_items, sorted_inds = zip(*sorted([(i,e) for i,e in enumerate(my_list)], key=itemgetter(1)))
x = [3,1,2]; numpy.argsort(x)
पैदावार [1,2,0]।
myList = [1, 2, 3, 100, 5]
sorted(range(len(myList)),key=myList.__getitem__)
[0, 1, 2, 4, 3]
के साथ उत्तर enumerate
अच्छे हैं, लेकिन मुझे व्यक्तिगत रूप से पसंद नहीं है कि लैम्बडा का उपयोग मूल्य के आधार पर किया जाता है। निम्नलिखित सिर्फ सूचकांक और मूल्य को उलट देता है, और उस तरह से। तो यह पहले मूल्य के आधार पर क्रमबद्ध करेगा, फिर सूचकांक द्वारा।
sorted((e,i) for i,e in enumerate(myList))
के साथ अपडेट किया गया उत्तर enumerate
और itemgetter
:
sorted(enumerate(a), key=lambda x: x[1])
# [(0, 1), (1, 2), (2, 3), (4, 5), (3, 100)]
सूचियों को एक साथ जिप करें: टपल में पहला तत्व इंडेक्स होगा, दूसरा वैल्यू है (फिर इसे टुपल के दूसरे मान का उपयोग करके सॉर्ट करें x[1]
, x टपल है)
या मॉड्यूल itemgetter
से उपयोग कर operator
रहे हैं:
from operator import itemgetter
sorted(enumerate(a), key=itemgetter(1))
मैंने परफ्लोट (मेरा एक प्रोजेक्ट) के साथ इन पर एक त्वरित प्रदर्शन जांच की और पाया कि इसके अलावा और कुछ भी सिफारिश करना कठिन है लेकिन सुन्न (लॉग स्केल पर ध्यान दें):
प्लॉट को फिर से तैयार करने के लिए कोड:
import perfplot
import numpy
def sorted_enumerate(seq):
return [i for (v, i) in sorted((v, i) for (i, v) in enumerate(seq))]
def sorted_enumerate_key(seq):
return [x for x, y in sorted(enumerate(seq), key=lambda x: x[1])]
def sorted_range(seq):
return sorted(range(len(seq)), key=seq.__getitem__)
def numpy_argsort(x):
return numpy.argsort(x)
perfplot.save(
"argsort.png",
setup=lambda n: numpy.random.rand(n),
kernels=[sorted_enumerate, sorted_enumerate_key, sorted_range, numpy_argsort],
n_range=[2 ** k for k in range(15)],
xlabel="len(x)",
)
अनिवार्य रूप से आपको एक करने की आवश्यकता है argsort
, आपको जो कार्यान्वयन की आवश्यकता है वह निर्भर करता है यदि आप बाहरी पुस्तकालयों (जैसे कि न्यूमपी) का उपयोग करना चाहते हैं या यदि आप निर्भरता के बिना शुद्ध-पायथन रहना चाहते हैं।
सवाल जो आपको खुद से पूछने की जरूरत है: क्या आप चाहते हैं
दुर्भाग्य से प्रश्न में उदाहरण यह स्पष्ट नहीं करता है कि वांछित क्या है क्योंकि दोनों एक ही परिणाम देंगे:
>>> arr = np.array([1, 2, 3, 100, 5])
>>> np.argsort(np.argsort(arr))
array([0, 1, 2, 4, 3], dtype=int64)
>>> np.argsort(arr)
array([0, 1, 2, 4, 3], dtype=int64)
argsort
कार्यान्वयन चुननायदि आपके पास अपने निपटान में नुम्पी है तो आप बस फ़ंक्शन numpy.argsort
या विधि का उपयोग कर सकते हैं numpy.ndarray.argsort
।
NumPy के बिना एक कार्यान्वयन का उल्लेख पहले से ही कुछ अन्य उत्तरों में किया गया था, इसलिए मैं यहाँ बेंचमार्क उत्तर के अनुसार सबसे तेज़ समाधान को फिर से लाऊँगा
def argsort(l):
return sorted(range(len(l)), key=l.__getitem__)
सरणी / सूची को सॉर्ट करने वाले सूचकांकों को प्राप्त करने के लिए आप बस argsort
सरणी या सूची पर कॉल कर सकते हैं । मैं यहाँ NumPy संस्करणों का उपयोग कर रहा हूँ, लेकिन पायथन कार्यान्वयन को समान परिणाम देना चाहिए
>>> arr = np.array([3, 1, 2, 4])
>>> np.argsort(arr)
array([1, 2, 0, 3], dtype=int64)
परिणाम में सूचक होते हैं जो क्रमबद्ध सरणी प्राप्त करने के लिए आवश्यक होते हैं।
चूँकि सॉर्ट किया गया एरे होगा [1, 2, 3, 4]
, एर्गोस्र्ड ऐरे में मूल में इन तत्वों के सूचक होते हैं।
1
और यह 1
मूल में सूचकांक पर है इसलिए परिणाम का पहला तत्व है 1
।2
सूचकांक पर है 2
मूल में तो परिणाम का दूसरा तत्व है 2
।3
सूचकांक पर है 0
मूल में तो परिणाम के तीसरे तत्व है 0
।4
और यह 3
मूल में सूचकांक पर है इसलिए परिणाम का अंतिम तत्व है 3
।इस मामले में आपको argsort
दो बार आवेदन करना होगा :
>>> arr = np.array([3, 1, 2, 4])
>>> np.argsort(np.argsort(arr))
array([2, 0, 1, 3], dtype=int64)
इस मामले में :
3
, जो तीसरा सबसे बड़ा मूल्य है, इसलिए यह 2
क्रमबद्ध सरणी / सूची में सूचकांक होगा इसलिए पहला तत्व है 2
।1
, जो सबसे छोटा मान है, इसलिए यह 0
क्रमबद्ध सरणी / सूची में सूचकांक होगा इसलिए दूसरा तत्व है 0
।2
, जो दूसरा सबसे छोटा मूल्य है, इसलिए यह 1
क्रमबद्ध सरणी / सूची में सूचकांक होगा ताकि तीसरा भाग है 1
।4
जो सबसे बड़ा मूल्य है, इसलिए यह 3
क्रमबद्ध सरणी / सूची में सूचकांक होगा इसलिए अंतिम तत्व है 3
।अन्य जवाब गलत हैं।
argsort
एक बार चलाने का उपाय नहीं है। उदाहरण के लिए, निम्न कोड:
import numpy as np
x = [3,1,2]
np.argsort(x)
पैदावार array([1, 2, 0], dtype=int64)
जो हम नहीं चाहते हैं।
उत्तर argsort
दो बार चलाने के लिए होना चाहिए :
import numpy as np
x = [3,1,2]
np.argsort(np.argsort(x))
देता है array([2, 0, 1], dtype=int64)
के रूप में उम्मीद।
x[2]
(3) सबसे छोटा तत्व बनाता है , और x[1]
(1) सबसे बड़ा तत्व (क्योंकि पूर्णांकों को क्रमबद्ध करने से उन्हें सबसे छोटे मूल्य से लेकर सबसे बड़े मूल्य तक का ऑर्डर देता है)। इसके अलावा, ओपी उदाहरण के साथ, एक एकल np.argsort([1, 2, 3, 100, 5])
पैदावार array([0, 1, 2, 4, 3])
, जो ओपी चाहता है सूचकांकों के लिए प्रतीत होता है।
arr = [1,2,3,100, 5, 9] res = np.argsort(arr) print(res)
तो हम [0 1 2 4 5 3]
गलत हैं।
arr[res]
पैदावार array([ 1, 2, 3, 5, 9, 100])
, जो पूरी तरह से ठीक लगती है, क्योंकि परिणामस्वरूप सरणी (बढ़ती) क्रम में है।
arr=[1,2,3,100, 5, 9]
, मैं आउटपुट के होने की उम्मीद करता हूं inds=[0,1,2,5,3,4]
, क्योंकि यह वह क्रम है जिसमें आप तत्वों को बढ़ाएंगे (तेजी से) - 1 0 स्थान पर है, 2 1 स्थान पर है, ...., 5 ऑन 1 4 वें स्थान पर 3 और 9 वें स्थान पर है। उस आउटपुट को प्राप्त करने के लिए ( inds
) मुझे argsort
दो बार चलाने की आवश्यकता है , जैसे मैंने उल्लेख किया है।
sort
लिए ओपी के उल्लेख को देखते हुए , मुझे लगता है कि ओपी अन्य कार्यक्षमता चाहता है, बहुत np.argsort
कुछ सामान्य रूप से उपयोग किया जाता है (जहां व्यक्ति arr[np.argsort[arr]]
अंतिम MATLAB उदाहरण में, सॉर्ट किए गए सरणी को प्राप्त करने के लिए उपयोग कर सकता है )। आपका उत्तर इस मामले / प्रश्न पर लागू होता है ।