2016-08-03 11 views
5

मैं एक नेस्टेड लूप को सदिश बनाना चाहता हूं, जो 300,000 सूचियों की सूची पर काम करेगा, इनमें से प्रत्येक सूची में 3 मान होते हैं। नेस्टेड लूप प्रत्येक सूचियों के मानों को अन्य सूचियों में संबंधित मानों के साथ तुलना करता है, और केवल उन सूची इंडेक्स को जोड़ देगा जिनके पास उनके बीच 0.1 का अधिकतम अंतर होता है। इस प्रकार, [0.234, 0.456, 0.567] युक्त एक सूची और [0.246, 0.479, 0.580] वाली एक सूची इस श्रेणी में गिर जाएगी, क्योंकि उनके संबंधित मान (यानी 0.234 और 0.246; 0.456 और 0.479; 0.567 और 0.580) में अंतर है उनके बीच 0.1 से कम।एक नेस्टेड लूप का चित्रण

मैं वर्तमान में निम्नलिखित नेस्टेड लूप का उपयोग करने के लिए उपयोग करता हूं, लेकिन वर्तमान में इसे पूरा करने में लगभग 58 घंटे लगेंगे (कुल 9 0 ट्रिलियन पुनरावृत्तियों);

import numpy as np 
variable = np.random.random((300000,3)).tolist() 
out1=list() 
out2=list() 
for i in range(0:300000): 
    for j in range(0:300000): 
     if ((i<j) and ((abs(variable[i][0]-variable[j][0]))<0.1) and ((abs(variable[i][1]-variable[j] [1]))<0.1) and ((abs(variable[i][2]-variable[j][2]))<0.1)): 
     out1.append(i) 
     out2.append(j) 
+0

आपका 'variable', यादृच्छिक है यह सिर्फ उदाहरण के लिए है, या आप वास्तव में अनुकरण कर रहे हैं कुछ? – Julien

+0

हां यह सिर्फ उदाहरण के लिए है - हकीकत में मेरे पास सूचियों के माध्यम से जेनरेट की गई सूचियों की एक सूची है, जिसमें वास्तव में डेटा का उल्लेख है जो मैंने उल्लेख किया है। – JBorg

उत्तर

3

scipy.spatial में देखो; इस तरह के स्थानिक प्रश्नों को कुशलता से हल करने के लिए इसमें बहुत सारी कार्यक्षमता है; विशेष रूप से KDTrees, अर्थात्:

import scipy.spatial 
out = scipy.spatial.cKDTree(variable).query_pairs(r=0.1, p=np.infinity) 
+0

इसे आजमाया; यह लौट रहा है "एक फ्लोट की आवश्यकता है"। मुझे लगता है कि यह कुछ आसान है; आपके जवाब का धन्यवाद! – JBorg

+0

आह मैंने दस्तावेज़ों को गलत समझा; वे इस विषय पर विशेष रूप से स्पष्ट नहीं हैं। संपादन का प्रयास करें। 'इन्फिनिटी-मानदंड' को उस मीट्रिक तक उबालना चाहिए जिसे आप ढूंढ रहे हैं; किसी भी घटक का अधिकतम पूर्ण मूल्य। –

+0

ध्यान दें कि दक्षता के लिए, पूरी तरह से एनडैरे के पक्ष में सूचियों से पहले जाना सर्वोत्तम है। यह आपके इनपुट पर लागू होता है, लेकिन आउटपुट भी; ध्यान दें कि आप इस कॉल में output_type = 'ndarray' kwarg जोड़ सकते हैं। –

3

उसके बाद NumPy funcs का उपयोग करना आसान बनाने के लिए NumPy सरणी में कनवर्ट करें। फिर, दो दृष्टिकोण सुझाए जा सकते हैं।

कार्य # 1

NumPy प्रसारण 3 डी सरणियों के लिए उन का विस्तार करने और एक vectorized ढंग से कार्य करने के लिए इस्तेमाल किया जा सकता। इस प्रकार, हम तो जैसे एक कार्यान्वयन के लिए होता है -

th = 0.1 # Threshold 
arr = np.asarray(variable) 
out1,out2 = np.where(np.triu((np.abs(arr[:,None,:] - arr) < th).all(-1),1)) 

कार्य # 2

चयनात्मक सूचकांक कि इस तरह की पुनरावृत्ति के लिए जिम्मेदार होगा का उपयोग करता है स्मृति क्षमता पर ध्यान देने के साथ

वैकल्पिक कार्यान्वयन -

th = 0.1 # Threshold 
arr = np.asarray(variable) 
R,C = np.triu_indices(arr.shape[0],1) 
mask = (np.abs(arr[R] - arr[C])<th).all(-1) 
out1,out2 = R[mask], C[mask] 
+0

यदि आपके पास रैम का टेराबाइट था, तो यह काम करेगा, हाँ :) –

+0

@EelcoHoogendoorn 'दृष्टिकोण # 2' कम भारी हो सकता है :) – Divakar

+0

ने कोशिश की, लेकिन स्मृति त्रुटि प्राप्त करने और बाहर; इसे केवल 30,000 सूचियों के साथ फिर से कोशिश की और अभी भी चल रहा है; मुझे लगता है कि यह अभी भी काफी समय ले रहा है? 256 जीबी रैम – JBorg

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