अजगर के साथ एक सरणी फेरबदल, अजगर के साथ सरणी आइटम क्रम यादृच्छिक


260

अजगर के साथ एक सरणी फेरबदल करने का सबसे आसान तरीका क्या है?


28
पायथन डॉक्यूमेंटेशन के सबसे उपयोगी बिट्स को हमेशा बेहतर SO Q & A फॉर्मेट में माइग्रेट करने के लिए।
charleslparker

1
क्या कोई विकल्प है जो मूल सरणी को म्यूट नहीं करता है लेकिन एक नया शिल्ड सरणी लौटाता है?
चार्ली पार्कर

5
आप एक नया सरणी (अनमॉडिफ़ाइड) प्राप्त कर सकते हैं new_array = random.sample( array, len(array) )
चार्ली पार्कर

जवाबों:


463
import random
random.shuffle(array)

3
क्या कोई विकल्प है जो मूल सरणी को म्यूट नहीं करता है लेकिन एक नया शिल्ड सरणी लौटाता है?
चार्ली पार्कर

@ चार्ली जो एक अलग सवाल में पूछना अच्छी बात होगी। (हो सकता है कि किसी और ने पहले ही पूछ लिया हो।)
डेविड जेड

13
विडंबना यह है कि यह पृष्ठ Google में शीर्ष हिट है, जब मैंने सिर्फ "अजगर फेरबदल सरणी" के लिए खोज की थी
जोशुआ ह्यूबर

2
@Charlie लोग इन प्रश्नों को Google करते हैं ताकि वे स्टैक ओवरफ़्लो जैसी जगहों पर उनके उत्तर पा सकें। जब तक यह डुप्लिकेट नहीं है तब तक स्टैक ओवरफ्लो को संसाधन के रूप में एक विकल्प बनाने के साथ कुछ भी गलत नहीं है
मैट

@ जजदबा वास्तव में पहले प्रश्न का उत्तर था। स्टैक ओवरफ्लो पर प्रश्न पूछने में कुछ भी गलत नहीं है, भले ही इसे Google पर कुछ खुदाई के साथ पाया जा सकता है। यह भविष्य के लोगों को स्टैकओवरफ्लो पर जवाब खोजने की अनुमति देता है जब वे अपनी खुदाई करते हैं।
मैट


36

वैकल्पिक तरीका यह sklearn का उपयोग कर

from sklearn.utils import shuffle
X=[1,2,3]
y = ['one', 'two', 'three']
X, y = shuffle(X, y, random_state=0)
print(X)
print(y)

आउटपुट:

[2, 1, 3]
['two', 'one', 'three']

लाभ: आप मानचित्रण को बाधित किए बिना एक साथ कई सरणियों को यादृच्छिक कर सकते हैं। और 'random_state' प्रजनन योग्य व्यवहार के लिए फेरबदल को नियंत्रित कर सकता है।


1
धन्यवाद, एक बार में दो सरणियों में फेरबदल करना बहुत उपयोगी है।
दिमित्री

1
इस के लिए देख रहा था, TNX!
n np

2
यह स्वीकृत उत्तर की तुलना में अधिक पूर्ण (और अक्सर अधिक उपयोगी) है
javadba

21

अन्य उत्तर सबसे आसान हैं, हालांकि यह थोड़ा कष्टप्रद है कि random.shuffleविधि वास्तव में कुछ भी नहीं लौटाती है - यह केवल दी गई सूची को सॉर्ट करती है। यदि आप कॉल को चेन करना चाहते हैं या केवल एक पंक्ति में एक फेरबदल सरणी घोषित करने में सक्षम हैं, तो आप कर सकते हैं:

    import random
    def my_shuffle(array):
        random.shuffle(array)
        return array

तो फिर आप लाइनों की तरह कर सकते हैं:

    for suit in my_shuffle(['hearts', 'spades', 'clubs', 'diamonds']):

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

2
मुझे लगता है कि यह एक स्टाइल की बात है। व्यक्तिगत रूप से मैं इस तथ्य को पसंद करता हूं कि मैं एक पंक्ति लिख सकता हूं ताकि यह सुनिश्चित हो सके कि एक जोड़े को अन्यथा क्या होगा। यह मुझे अजीब लगता है कि एक भाषा जिसका उद्देश्य कार्यक्रमों को यथासंभव कम करने की अनुमति देना है, इन मामलों में पारित वस्तु को वापस नहीं करना है। चूँकि यह इनपुट को जगह में बदल देता है, आप बिना किसी समस्या के इस संस्करण में कॉल के लिए कॉल को random.shuffle में बदल सकते हैं।
मार्क रोड्स

12
अजगर वास्तव में यथासंभव संक्षिप्त होने का लक्ष्य नहीं रखता है। अजगर का उद्देश्य स्पष्टता के साथ पठनीयता को संतुलित करना है। ऐसा इसलिए होता है क्योंकि यह काफी संक्षिप्त है, क्योंकि यह बहुत उच्च स्तरीय भाषा है। पायथन का अपना बिल्ट-इन आमतौर पर (हमेशा नहीं) प्रयास होता है या तो "functionlike" हो (कोई मान है, लेकिन साइड इफेक्ट नहीं है) या हो "procedurelike" (साइड इफेक्ट के माध्यम से काम करते हैं, और कुछ भी वापस नहीं है)। यह बयानों और अभिव्यक्तियों के बीच पायथन के काफी सख्त अंतर के साथ हाथ से जाता है।
जॉन वाई

अच्छा लगा। मैं इसे तुरंत कोड में अंतर देखने के लिए my_shuffle का नाम बदलने का सुझाव देता हूं।
जब्बा

हो सकता है, लेकिन यह समय से पहले अनुकूलन हो सकता है (यह सहायक हो सकता है, लेकिन फेरबदल की आवश्यकता स्पष्ट रूप से सरणी को वापस करने की आवश्यकता नहीं है)। इसके अलावा, फेरबदल (सरणी) फेरबदल के कुछ उपयोग के बाद 3 + n (बार उपयोग) के विपरीत केवल 2 लाइनें होंगी, हालांकि मुझे लगता है कि यदि आप इसे कई बार उपयोग करते हैं तो यह एक बचत होगी। यहाँ एक शानदार वीडियो है जो इस प्रकार की बात करता है (जैसे प्रेत आवश्यकताओं और समय से पहले अनुकूलन) - pyvideo.org/video/880/stop-writing-classes
हारून न्यूटन

12

जब नियमित पायथन सूचियों के साथ काम करते हैं, random.shuffle()तो पिछले उत्तरों की तरह ही काम करेंगे।

लेकिन जब यह ndarray( numpy.array) आता है, random.shuffleतो मूल को तोड़ने लगता है ndarray। यहाँ एक उदाहरण है:

import random
import numpy as np
import numpy.random

a = np.array([1,2,3,4,5,6])
a.shape = (3,2)
print a
random.shuffle(a) # a will definitely be destroyed
print a

महज प्रयोग करें: np.random.shuffle(a)

जैसे random.shuffle, np.random.shuffleजगह में सरणी फेरबदल।


2
नष्ट होने का क्या मतलब है, बिल्कुल? (मेरा मतलब है, इस संदर्भ में - मैं एक
ईएलएल

अगर मैं A = np.array (रेंज (9)) की कोशिश करता हूं। रिशेप ([3,3])
निकोलस मैकार्थी

11

यदि आप एक नई सरणी चाहते हैं, तो आप इसका उपयोग कर सकते हैं sample:

import random
new_array = random.sample( array, len(array) )

3

आप यादृच्छिक सरणी के साथ अपने सरणी को सॉर्ट कर सकते हैं

sorted(array, key = lambda x: random.random())

कुंजी को केवल एक बार पढ़ा जाना चाहिए ताकि तुलना के दौरान आइटम की तुलना अभी भी कुशल हो।

लेकिन जैसे दिखते हैं random.shuffle(array) C में लिखा गया है वैसा ही तेज होगा


1
क्या यह सरणी के प्रत्येक तत्व के लिए एक नया यादृच्छिक तत्व बनाता है?
जावदबा

@javadba नहीं, यह केवल यादृच्छिक सूचकांक द्वारा एक सरणी को छाँटता है जो सरणी को समाप्त कर देगा
त्रिन

1
क्षमा करें, मैं शायद स्पष्ट नहीं था मेरा मतलब यह नहीं था कि arrayमेरा मतलब Randomतत्व था: अर्थातlambdarandom.random() नया पैदा हो सकता है Randomवर्ग उदाहरण हर बार। मुझे वास्तव में यकीन नहीं है: javaइसमें ऐसा करने का गलत तरीका होगा: आपको एक बनाना चाहिए Random rng = Random()और फिर आह्वान करना चाहिए rng.nextGaussian()। लेकिन यकीन नहीं होता कि अजगर कैसे random.random()काम करता है
जावदबा

1
हालांकि आपका कोड उत्तर के रूप में सही हो सकता है लेकिन आपका कोड क्या करता है, इसे विस्तृत करते हुए, यह आपके उत्तर की गुणवत्ता में सुधार कर सकता है। लेख की जाँच करें: मैं एक अच्छा उत्तर कैसे लिखूँ?
लूफी

1

पिछले उत्तरों के अलावा, मैं एक और समारोह शुरू करना चाहूंगा।

numpy.random.shuffleसाथ ही random.shuffleजगह-जगह पर फेरबदल करते हैं। हालाँकि, यदि आप एक फेरबदल सरणी वापस करना चाहते हैं numpy.random.permutationउपयोग करने के लिए फ़ंक्शन है।


1

मुझे नहीं पता कि मैंने इसका इस्तेमाल किया है, random.shuffle()लेकिन यह मेरे लिए 'कोई नहीं' लौटाता है, इसलिए मैंने इसे लिखा, जो किसी के लिए उपयोगी हो सकता है

def shuffle(arr):
    for n in range(len(arr) - 1):
        rnd = random.randint(0, (len(arr) - 1))
        val1 = arr[rnd]
        val2 = arr[rnd - 1]

        arr[rnd - 1] = val1
        arr[rnd] = val2

    return arr

2
हाँ, यह कोई भी नहीं लौटाता है, लेकिन सरणी संशोधित है, अगर आप वास्तव में कुछ वापस करना चाहते हैं तो इस आयात को रैंडम डिफ शफल (गिरफ्तारी) करें: random.shuffle (arr) रिटर्न
अरेस्ट

0
# arr = numpy array to shuffle

def shuffle(arr):
    a = numpy.arange(len(arr))
    b = numpy.empty(1)
    for i in range(len(arr)):
        sel = numpy.random.random_integers(0, high=len(a)-1, size=1)
        b = numpy.append(b, a[sel])
        a = numpy.delete(a, sel)
    b = b[1:].astype(int)
    return arr[b]

0

विदित हो कि random.shuffle() इसका उपयोग बहु-आयामी सरणियों पर नहीं किया जाना चाहिए क्योंकि यह दोहराव का कारण बनता है।

कल्पना कीजिए कि आप अपने पहले आयाम के साथ एक सरणी फेरबदल करना चाहते हैं, हम निम्नलिखित परीक्षा उदाहरण बना सकते हैं,

import numpy as np
x = np.zeros((10, 2, 3))

for i in range(10):
   x[i, ...] = i*np.ones((2,3))

इतना है कि पहली धुरी के साथ, i-th तत्व एक 2x3 मैट्रिक्स से मेल खाता है, जहां सभी तत्व समान हैं।

यदि हम बहु-आयामी सरणियों के लिए सही फेरबदल फ़ंक्शन का उपयोग करते हैं, अर्थात np.random.shuffle(x), सरणी को वांछित के रूप में पहले अक्ष के साथ फेरबदल किया जाएगा। हालाँकि, उपयोग random.shuffle(x)से पुनरावृत्ति होगी। आप इसे len(np.unique(x))फेरबदल करने के बाद चला सकते हैं जो आपको 10 (जैसा कि अपेक्षित हो) np.random.shuffle()का उपयोग करते समय केवल 5 के आसपास देता है random.shuffle()

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