2010-10-08 14 views
13

मैं न्यूमपी में कुछ मॉडलिंग रूटीन लिख रहा हूं जिसे NumPy सरणी से यादृच्छिक रूप से कक्षों का चयन करने और उन पर कुछ प्रसंस्करण करने की आवश्यकता है। सभी कोशिकाओं को प्रतिस्थापन के बिना चुना जाना चाहिए (जैसा कि, एक बार सेल चुना गया है, इसे फिर से नहीं चुना जा सकता है, लेकिन सभी कोशिकाओं को अंत तक चुना जाना चाहिए)।NumPy सरणी से यादृच्छिक रूप से कक्षों का चयन करें - प्रतिस्थापन

मैं आईडीएल से संक्रमण कर रहा हूं जहां मुझे ऐसा करने का अच्छा तरीका मिल सकता है, लेकिन मुझे लगता है कि न्यूमपी के पास ऐसा करने का एक अच्छा तरीका भी है। आप क्या सुझाव देंगे?

अद्यतन: मुझे लगता है कि मैं 2 डी सरणियों पर यह करने के लिए कोशिश कर रहा हूँ, और इसलिए 2 डी का एक सेट प्राप्त कहा है चाहिए वापस सूचकांक।

उत्तर

20

यदि आपको अभी भी मूल सरणी की आवश्यकता है तो numpy.random.shuffle या numpy.random.permutation का उपयोग करने के बारे में कैसे?

आप यथा-स्थान सरणी को बदलने के लिए की तुलना में आप इस तरह एक सूचकांक सरणी बना सकते हैं की जरूरत है: मुझे लगता है एक 2 डी सरणी के लिए

your_array = <some numpy array> 
index_array = numpy.arange(your_array.size) 
numpy.random.shuffle(index_array) 

print your_array[index_array[:10]] 
+0

आपके उत्तर के लिए धन्यवाद। ऐसा लगता है कि मुझे अपने प्रश्न में उल्लेख किया जाना चाहिए था कि यह 2 डी सरणी है ... और मैं प्रतिस्थापन के बिना यादृच्छिक रूप से प्रत्येक सेल के लिए 2 डी सरणी सूचकांक प्राप्त करना चाहता हूं। क्या यह आसानी से करने का कोई तरीका है? मैं – robintw

+2

@robintw - 'numpy.random.shuffle' को पूरी तरह से एन-आयामी सरणी पर काम करना चाहिए। यदि आप इंडिसीज चाहते हैं, तो आप पंक्ति और कॉलम इंडेक्स सरणी ('मेश्रिड' में देखें) बनाने और फिर उन्हें शफल करने का प्रयास कर सकते हैं। –

+0

@robintw: 2 डी सरणी कोई समस्या नहीं है, आप बस 1 डी के बजाय 2 डी प्राप्त करने के लिए 'reshape() 'कर सकते हैं :) – Wolph

2

@WoLpH

से अच्छा जवाब का विस्तार कहीं भी होगी आप जो चाहते हैं उस पर निर्भर करते हैं या सूचकांक के बारे में जानना चाहते हैं।

आप कुछ इस तरह कर सकता है:

data = np.arange(25).reshape((5,5)) 

x, y = np.where(a = a) 
idx = zip(x,y) 
np.random.shuffle(idx) 

या

data = np.arange(25).reshape((5,5)) 

grid = np.indices(data.shape) 
idx = zip(grid[0].ravel(), grid[1].ravel()) 
np.random.shuffle(idx) 

फिर आप अधिक तेज़ी से दोहराने में सूची idx उपयोग कर सकते हैं के रूप में आप चाहते हैं बेतरतीब ढंग से 2 डी सरणी सूचकांक आदेश दिया, और प्राप्त करने के लिए उस सूचकांक के मान data से बाहर जो अपरिवर्तित बनी हुई है।

नोट: आप भी itertools.product के माध्यम से बेतरतीब ढंग से आदेश दिया सूचकांक उत्पन्न कर सकता है, इस स्थिति में आप उपकरण के इस सेट के साथ अधिक सहज हैं।

+0

पहले उदाहरण में' a' क्या है? इसके अलावा अभिव्यक्ति 'a = a'' True' का मूल्यांकन करती है जो कि आप एक numpy 'कहां' कॉल ('numpy.where' मुखौटा सरणी में लेता है) से नहीं हो सकता है। क्या आपका मतलब था 'x, y = np.where (डेटा == डेटा)'? – Hooked

1

उपयोग random.sample 0 में ints उत्पन्न करता है .. A.size कोई डुप्लिकेट के साथ, फिर उन्हें सूचकांक जोड़े को विभाजित:

import random 
import numpy as np 

def randint2_nodup(nsample, A): 
    """ uniform int pairs, no dups: 
     r = randint2_nodup(nsample, A) 
     A[r] 
     for jk in zip(*r): 
      ... A[jk] 
    """ 
    assert A.ndim == 2 
    sample = np.array(random.sample(xrange(A.size), nsample)) # nodup ints 
    return sample // A.shape[1], sample % A.shape[1] # pairs 


if __name__ == "__main__": 
    import sys 

    nsample = 8 
    ncol = 5 
    exec "\n".join(sys.argv[1:]) # run this.py N= ... 
    A = np.arange(0, 2*ncol).reshape((2,ncol)) 

    r = randint2_nodup(nsample, A) 
    print "r:", r 
    print "A[r]:", A[r] 
    for jk in zip(*r): 
     print jk, A[jk] 
1

मान लीजिए कि आप आकार 8x3 के डेटा बिंदुओं की एक सरणी करते

data = np.arange(50,74).reshape(8,-1) 

आप वास्तव में नमूने के लिए, जैसा कि आप कहते हैं कि चाहते हैं, 2 डी जोड़े, इस है कि मैं के बारे में सोच सकते हैं करने के लिए सबसे कॉम्पैक्ट तरह से, के रूप में सभी सूचकांकों है:

#generate a permutation of data's size, coerced to data's shape 
idxs = divmod(np.random.permutation(data.size),data.shape[1]) 

#iterate over it 
for x,y in zip(*idxs): 
    #do something to data[x,y] here 
    pass 

मो आम तौर पर, हालांकि, अक्सर 2 डी सरणी को 2 डी सरणी के रूप में आसानी से घुमाने के लिए उपयोग करने की आवश्यकता नहीं होती है, इस मामले में कोई भी अधिक कॉम्पैक्ट हो सकता है। बस सरणी पर 1 डी व्यू बनाएं और खुद को कुछ इंडेक्स-wrangling बचाओ।

flat_data = data.ravel() 
flat_idxs = np.random.permutation(flat_data.size) 
for i in flat_idxs: 
    #do something to flat_data[i] here 
    pass 

यह अभी भी 2 डी "मूल" सरणी चाहें, उतनी बार दूसरे स्थान पर रखना होगा। इसे देखने के लिए, कोशिश करें:

flat_data[12] = 1000000 
print data[4,0] 
#returns 1000000 
1

लोग numpy संस्करण 1 का उपयोग कर रहे हैं।7 या बाद में बिल्टिन फ़ंक्शन numpy.random.choice

3

का उपयोग भी कर सकते हैं इन सभी उत्तरों को मुझे थोड़ा गड़बड़ लग रहा था।

मुझे लगता है कि आपके पास एक बहु-आयामी सरणी है जिसमें से आप सूचकांक की एक विस्तृत सूची उत्पन्न करना चाहते हैं। आप इन इंडेक्स को शफल करना चाहते हैं ताकि आप प्रत्येक सरणी तत्वों को यादृच्छिक क्रम में एक्सेस कर सकें।

निम्नलिखित कोड एक सरल और सीधी-सपाट ढंग से यह कर देगा:

#!/usr/bin/python 
import numpy as np 

#Define a two-dimensional array 
#Use any number of dimensions, and dimensions of any size 
d=numpy.zeros(30).reshape((5,6)) 

#Get a list of indices for an array of this shape 
indices=list(np.ndindex(d.shape)) 

#Shuffle the indices in-place 
np.random.shuffle(indices) 

#Access array elements using the indices to do cool stuff 
for i in indices: 
    d[i]=5 

print d 

मुद्रण d सत्यापित है कि सभी तत्वों को एक्सेस किया गया था।

ध्यान दें कि सरणी में आयामों की संख्या हो सकती है और आयाम किसी भी आकार का हो सकता है।

इस दृष्टिकोण का एकमात्र नकारात्मक पक्ष यह है कि यदि d बड़ा है, तो indices बहुत बड़ा हो सकता है। इसलिए, जनरेटर होना अच्छा लगेगा। अफसोस की बात है, मैं इस बारे में नहीं सोच सकता कि कैसे एक शफ़ल इटरेटर को हाथ से बनाया जाए।

संबंधित मुद्दे