उतरते क्रम में एक सुन्न सरणी को कुशलता से छांटना?


121

मुझे आश्चर्य है कि यह विशिष्ट प्रश्न पहले नहीं पूछा गया है, लेकिन मैं वास्तव में एसओ पर नहीं मिला और न ही इसके प्रलेखन पर np.sort

मान लें कि मेरे पास एक यादृच्छिक संख्या में पूर्णांक वाले सरणी हैं, जैसे:

> temp = np.random.randint(1,10, 10)    
> temp
array([2, 4, 7, 4, 2, 2, 7, 6, 4, 4])

यदि मैं इसे क्रमबद्ध करता हूं, तो मुझे डिफ़ॉल्ट रूप से आरोही क्रम मिलता है:

> np.sort(temp)
array([2, 2, 2, 4, 4, 4, 4, 6, 7, 7])

लेकिन मैं चाहता हूं कि समाधान को अवरोही क्रम में हल किया जाए।

अब, मुझे पता है कि मैं हमेशा कर सकता हूं:

reverse_order = np.sort(temp)[::-1]

लेकिन क्या यह अंतिम कथन कुशल है ? क्या यह आरोही क्रम में एक प्रति नहीं बनाता है, और फिर उलटी क्रम में परिणाम प्राप्त करने के लिए इस प्रति को उलट देता है? यदि यह वास्तव में मामला है, तो क्या एक कुशल विकल्प है? यह np.sortरिवर्स ऑर्डर में चीजों को प्राप्त करने के लिए सॉर्ट ऑपरेशन में तुलना के संकेत को बदलने के लिए मापदंडों को स्वीकार नहीं करता है ।

जवाबों:


139

temp[::-1].sort()जगह में सरणी को सॉर्ट करें, जबकि np.sort(temp)[::-1]एक नया सरणी बनाता है।

In [25]: temp = np.random.randint(1,10, 10)

In [26]: temp
Out[26]: array([5, 2, 7, 4, 4, 2, 8, 6, 4, 4])

In [27]: id(temp)
Out[27]: 139962713524944

In [28]: temp[::-1].sort()

In [29]: temp
Out[29]: array([8, 7, 6, 5, 4, 4, 4, 4, 2, 2])

In [30]: id(temp)
Out[30]: 139962713524944

30
धन्यवाद, लेकिन यह कैसे temp[::-1].sort()पता चलता है कि इसे रिवर्स ऑर्डर में सॉर्ट करना है ?? जिस तरह से मैंने इसे पढ़ा है: मूल सरणी को उल्टा करें, और फिर इसे क्रमबद्ध करें (आरोही क्रम में)। मूल सरणी (एक यादृच्छिक क्रम में आने) को उलटने और फिर आरोही क्रम में छाँटने से सरणी को उलट क्रम में वापस क्यों आएगा?
एमिलियो वाज़केज़-रीना

14
क्या यह व्यवहार प्रलेखित है, क्योंकि यह बहुत अचूक है।
ईबार

18
ऐसा लगता है कि यह काम करता है क्योंकि यह [::-1]वास्तव में सरणी को पुन: व्यवस्थित करने के बजाय सरणी के ऊपर से पुनरावृत्त करने के लिए सुन्न बताता है। इसलिए जब इन-प्लेस सॉर्ट होता है, तो यह वास्तव में आरोही क्रम में सॉर्ट करता है और बिट्स को इधर-उधर कर देता है, लेकिन पीछे की ओर जाने वाले हिस्से को अछूता छोड़ देता है।
पेरिमोसोकार्डिया 1

45
a=np.array((...))मुहावरे के साथ a[::-1]कुछ भी उल्टा नहीं होता है, यह एक ही डेटा पर एक नया दृश्य है , विशेष रूप से एक दर्पण दृश्य है। विधि a[::-1].sort() प्रतिबिंबित छवि पर चल रही है , जिसका अर्थ है कि जब चालित छवि में एक छोटी सी वस्तु को छोड़ दियाsort जाता है , तो वास्तव में यह इसे सरणी के वास्तविक मेमोरी ब्लॉक में दाईं ओर ले जा रहा है । मिरर किए गए दृश्य को आरोही क्रम में सॉर्ट किया जाता है, वास्तविक डेटा को अवरोही क्रम में सॉर्ट किया जाता है। कुछ अलग सिक्कों और एक दर्पण के साथ अपने आप से इसे घर पर आज़माएं! a
gboffi

30
यह वास्तव में पठनीय पैरामीटर के रूप में जोड़ा जाना चाहिए, जैसे np.sort(temp,order='descending')कि इन प्रकार के हैक्स की आवश्यकता नहीं है
नाथन

92
>>> a=np.array([5, 2, 7, 4, 4, 2, 8, 6, 4, 4])

>>> np.sort(a)
array([2, 2, 4, 4, 4, 4, 5, 6, 7, 8])

>>> -np.sort(-a)
array([8, 7, 6, 5, 4, 4, 4, 4, 2, 2])

2
सबसे अच्छा जवाब - लघु और मीठा, और axisजिस np.sortपर आवेदन किया गया था , उसका कोई ज्ञान आवश्यक नहीं है।
ल्यूक डेविस

2
यह इस बात से अलग है np.sort(temp)[::-1]कि यह nanसामने के बजाय सरणी के पीछे स्थित है। चाहे वह अच्छा हो या बुरा बहस के लिए है ..
बेन

15

छोटे सरणियों के लिए, मैं np.argsort()हल किए गए नकारात्मक सरणी के सूचकांकों का उपयोग करके सुझाव देता हूं , जो क्रमबद्ध सरणी को उलटने की तुलना में थोड़ा तेज है:

In [37]: temp = np.random.randint(1,10, 10)

In [38]: %timeit np.sort(temp)[::-1]
100000 loops, best of 3: 4.65 µs per loop

In [39]: %timeit temp[np.argsort(-temp)]
100000 loops, best of 3: 3.91 µs per loop

a[np.argsort(-a)]शायद इस पृष्ठ पर किसी अन्य के लिए सबसे अच्छा तरीका है। कोई -1 स्टेप रिवर्सल और एक कम माइनस साइन के बारे में सोचने के लिए।
जारद

8

दुर्भाग्य से जब आपके पास एक जटिल सरणी होती है, केवल np.sort(temp)[::-1]ठीक से काम करती है। यहाँ उल्लिखित दो अन्य विधियाँ प्रभावी नहीं हैं।


@ aishtain4: "कॉम्प्लेक्स एरे" द्वारा, क्या आपका मतलब कॉम्प्लेक्स नंबरों की एक सरणी से है? या क्या आपका मतलब किसी अन्य प्रकार की जटिलता के साथ एक सरणी है (यदि ऐसा है तो pls निर्दिष्ट करें कि किस प्रकार की जटिलता है)। किसी भी स्थिति में, मुझे लगता है कि आप अपने उत्तर के बारे में कुछ और विस्तृत कर सकते हैं, अन्य तरीकों से कैसे विफल हो सकते हैं। धन्यवाद।
झरने के स्रोतों

@ फाउंटेनहेड का मतलब है जटिल संख्याओं की सरणी। चूँकि यह एक पुराना प्रश्न है, इसलिए मुझे अपने परीक्षण के मामले को अधिक विस्तृत रूप से याद नहीं है।
ऐशट्रेन

7

आयामों से सावधान रहें।

चलो

x  # initial numpy array
I = np.argsort(x) or I = x.argsort() 
y = np.sort(x)    or y = x.sort()
z  # reverse sorted array

पूरा उलटा

z = x[-I]
z = -np.sort(-x)
z = np.flip(y)
  • flipआवश्यक1.15 पिछले संस्करणों में बदल गया है । समाधान: ।1.14 axispip install --upgrade numpy

पहला आयाम उलट

z = y[::-1]
z = np.flipud(y)
z = np.flip(y, axis=0)

दूसरा आयाम उलट

z = y[::-1, :]
z = np.fliplr(y)
z = np.flip(y, axis=1)

परिक्षण

100 × 10 × 10 सरणी पर 1000 बार परीक्षण।

Method       | Time (ms)
-------------+----------
y[::-1]      | 0.126659  # only in first dimension
-np.sort(-x) | 0.133152
np.flip(y)   | 0.121711
x[-I]        | 4.611778

x.sort()     | 0.024961
x.argsort()  | 0.041830
np.flip(x)   | 0.002026

यह मुख्य रूप से बजाय reindexing के कारण है argsort

# Timing code
import time
import numpy as np


def timeit(fun, xs):
    t = time.time()
    for i in range(len(xs)):  # inline and map gave much worse results for x[-I], 5*t
        fun(xs[i])
    t = time.time() - t
    print(np.round(t,6))

I, N = 1000, (100, 10, 10)
xs = np.random.rand(I,*N)
timeit(lambda x: np.sort(x)[::-1], xs)
timeit(lambda x: -np.sort(-x), xs)
timeit(lambda x: np.flip(x.sort()), xs)
timeit(lambda x: x[-x.argsort()], xs)
timeit(lambda x: x.sort(), xs)
timeit(lambda x: x.argsort(), xs)
timeit(lambda x: np.flip(x), xs)

6

नमस्कार मैं एक दो आयामी सुन्न सरणी को उलटने के लिए एक समाधान की खोज कर रहा था, और मुझे ऐसा कुछ भी नहीं मिला जो काम किया हो, लेकिन मुझे लगता है कि मैं एक समाधान पर ठोकर खाई हूं जो मैं सिर्फ किसी एक ही नाव में होने की स्थिति में अपलोड कर रहा हूं।

x=np.sort(array)
y=np.fliplr(x)

np.sort सॉर्टिंग आरोही है जो आप नहीं चाहते हैं, लेकिन कमांड फ़्लिप्र पंक्तियों को दाईं ओर छोड़ता है! काम करने लगता है!

आशा है कि यह आपकी मदद करता है!

मुझे लगता है कि यह ऊपर -np.sort (-a) के बारे में सुझाव के समान है, लेकिन मुझे इस बात के लिए बंद कर दिया गया कि यह हमेशा काम नहीं करता है। शायद मेरा समाधान हमेशा काम नहीं करेगा लेकिन मैंने इसे कुछ सरणियों के साथ परीक्षण किया है और ठीक लगता है।


1

आप पहले सरणी को सॉर्ट कर सकते हैं (डिफ़ॉल्ट रूप से आरोही) और फिर np.flip () ( https://docs.scipy.org/doc/numpy/reference/generated/numpy.flip.html ) लागू करें

FYI करें यह डेटाइम वस्तुओं के साथ भी काम करता है।

उदाहरण:

    x = np.array([2,3,1,0]) 
    x_sort_asc=np.sort(x) 
    print(x_sort_asc)

    >>> array([0, 1, 2, 3])

    x_sort_desc=np.flip(x_sort_asc) 
    print(x_sort_desc)

    >>> array([3,2,1,0])

जिनके सरणियों में NaN है, वे सावधान रहें, विभिन्न प्रस्तावित विधियाँ विभिन्न परिणाम उत्पन्न करती हैं। उदाहरण के लिए अगर x = np.array([2,3,np.nan,1,0]) तब np.flip(np.sort(x))एप्रोच पैदावार करता है [नैनो 3. 2. 1. 0.], जबकि -np.sort(-x)एप्रोच से पैदावार होती है [3. 2. 2. 1. 0. नेन]।
उवे मेयर

1

यहाँ एक त्वरित चाल है

In[3]: import numpy as np
In[4]: temp = np.random.randint(1,10, 10)
In[5]: temp
Out[5]: array([5, 4, 2, 9, 2, 3, 4, 7, 5, 8])

In[6]: sorted = np.sort(temp)
In[7]: rsorted = list(reversed(sorted))
In[8]: sorted
Out[8]: array([2, 2, 3, 4, 4, 5, 5, 7, 8, 9])

In[9]: rsorted
Out[9]: [9, 8, 7, 5, 5, 4, 4, 3, 2, 2]

-3

मैं यह प्रयोग करने का सुझाव ...

np.arange(start_index, end_index, intervals)[::-1]

उदाहरण के लिए:

np.arange(10, 20, 0.5)
np.arange(10, 20, 0.5)[::-1]

फिर आपका परिणाम:

[ 19.5,  19. ,  18.5,  18. ,  17.5,  17. ,  16.5,  16. ,  15.5,
    15. ,  14.5,  14. ,  13.5,  13. ,  12.5,  12. ,  11.5,  11. ,
    10.5,  10. ]

1
यह समस्या का समाधान कैसे करता है? आप बस एक पूरी तरह से असंबंधित, नया (अवरोही) सरणी बना रहे हैं - जिस तरह से - अधिक कुशल तरीके से किया जा सकता है np.arange(20-0.5, 10-0.5, -0.5):। लेकिन यह एक अलग कहानी है और खराब पठनीयता, बहस के कारण हो सकती है। इनपुट ऐरे को क्रमबद्ध नहीं किया जाता है
डैनियल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.