2015-12-14 9 views
7

मेरे पास 2016 की लंबाई है, लेकिन केवल 242 डेटा हैं, बाकी को कोई भी सेट नहीं है। मेरा उद्देश्य आईडीडब्ल्यू (व्यस्त दूरी भारोत्तोलन) के एक साधारण रूप के साथ सभी अंतराल को भरने के लिए मूल्यों के बीच अंतर करना है। तो मेरी स्क्रिप्ट का काम है:सूची में पड़ोसियों को खोजने का सबसे प्रभावी तरीका

  • MyList
  • के सभी आइटम्स से अधिक दोहराएं MyList एक मूल्य (कि है नहीं कोई नहीं), बस इसे
  • कॉपी आप एक मिल जाए "शामिल हैं कोई भी नहीं "मेरी सूची में, मेरी सूची
  • में सभी वस्तुओं की दूरी की गणना करके बाएं और दाएं पड़ोसी की स्थिति/मूल्य प्राप्त करें, दोनों पड़ोसियों के अंतर के लिए एक अंतरित मूल्य की गणना करें (वे दूर हैं, वे जितना कम वजन कम करेंगे)

मान लें कि हम केवल 14 आइटम (5 वैध वाले) की एक छोटी सूची है:

myList = [26, None, None, None, 31, None, None, 58, None, 42, None, None, None, 79] 
resultList = [None] * len(myList) 

for i in range(len(myList): 
    if not myList[i] is None: 
     resultList[i] = myList[i] 
    else: 
     distance = [i - j for j in range(len(myList)) if not myList[j] is None] 
     neighbors = min([n for n in dist if n>0]), max([n for n in dist if n<0]) 
     # rest of the interpolation (not important for my question): 
     neighbors_c = [(1/float(n))**2 for n in neighbors] 
     c_sum = sum(neighbors_c) 
     neighbors_c = [n/c_sum for n in neighbors_c] 
     resultList = myList[i-neighbors[0]]*neighbors_c[0] + myList[i-neighbors[1]]*neighbors_c[1] 

मैं कई कई डेटा सेट के लिए कर रहा हूँ कि। मुझे पता चला कि यह विधि प्रति डेटा सेट के बारे में 0.5 9सीसी लेती है। मुझे परेशान करने वाला यह तथ्य है कि मेरी सूची सभी को हल किया गया है, लेकिन मुझे केवल 2 मानों की आवश्यकता होगी। तो 99% दूरी की गणना कुछ भी नहीं के लिए की जाती है। सूची समझ

तो बजाय:

distance = [i - j for j in range(len(myList)) if not myList[j] is None] 

मैं के लिए लूप एक उचित करते हैं, क्योंकि तब स्पष्ट रूप से यह सबसे करीब मूल्यों में भाग, यात्रा रोक ij के बाद नकारात्मक हो जाता है: यह मुझे दो प्रयास करने के लिए नेतृत्व किया जिसके बाद दूरी शून्य से पारित है और इस तरह बड़ा फिर से बन रहा छोड़ने:

dist = [] 
for j in range(len(myList)): 
    if not myList[j] is None: 
     dist.append(i-j) 
     if i-j < 0: break 

इस विधि मैं डेटा सेट प्रति 0.38sec करने के लिए नीचे प्राप्त करने में सक्षम था के साथ। मेरी सूची में सभी वस्तुओं पर पुनरावृत्ति करते समय, यह दूसरी विधि शुरुआत में जल्दी होती है (आइटम 2, 3, 4 वें, ... लूप के बाद मारा जाता है और तुरंत छोड़ दिया जाता है), लेकिन आखिरी वस्तुओं के लिए कोई सुधार नहीं है, क्योंकि पुनरावृत्ति हमेशा शुरू होती है जे = 0 पर।

मुझे आश्चर्य है कि क्या आप डेटा सेट में किसी विशिष्ट संख्या के दो पड़ोसियों को खोजने के किसी भी तेज तरीके से सोच सकते हैं, बिना सभी दूरीों की जांच किए और केवल सबसे बड़ा नकारात्मक और छोटे सकारात्मक लेते हैं।

इसके अलावा, मैं पाइथन के लिए काफी नया हूं, इसलिए कृपया मुझे बताएं कि क्या आपको मेरी स्क्रिप्ट में अन्य अन-पायथनिक अभिव्यक्तियां मिलती हैं। बहुत बहुत धन्यवाद दोस्तों!

+1

Numpy कुछ निकटतम-पड़ोसी-एल्गोरिदम प्रदान करता है जिन्हें आप [उन्हें] देख सकते हैं (http://docs.scipy.org/doc/scipy/reference/spatial.html#nearest-neighbor-queries) – albert

+1

और वहां 'pandas.Series.interpolate' फ़ंक्शन है जो यह सब करता है। – pacholik

+0

प्रश्न के किसी भी उत्तर के बारे में [पाइथन के साथ व्यस्त दूरी भारित (आईडीडब्ल्यू) इंटरपोलेशन] (http://stackoverflow.com/questions/3104781/inverse-distance-weighted-idw-interpolation-with-python)? – ojdo

उत्तर

2

अद्यतन: यहाँ कैसे numpy interp साथ यह करना है:

import numpy as np 

myList = [26, None, None, None, 31, None, None, 58, None, 42, None, None, None, 79] 

values = [(i, val) for i, val in enumerate(myList) if val is not None] 

xp, fp = zip(*values) 

print(xp) # (0, 4, 7, 9, 13) 
print(fp) # (26, 31, 58, 42, 79) 

result = np.interp(np.arange(len(myList)), xp, fp) 
print(result) # [ 26. 27.25 28.5 29.75 31. 40. 49. 58. 50. 42. 51.25 60.5 69.75 79. ] 

मूल पोस्ट:

दूसरों को पहले से ही सुझाव दिया है के रूप में, अपने सबसे अच्छे कुछ प्रक्षेप का उपयोग कर के साथ बंद को पहले से ही लागू किया numpy या पांडा में।

myList = [26, None, None, None, 31, None, None, 58, None, 42, None, None, None, 79] 

resultList = [] 

# first lets split the list into sublists that group the numbers 
# and the Nones into groups 
for i, item in enumerate(myList): 
    if i == 0: 
     resultList.append([item]) 
    else: 
     if type(resultList[-1][-1]) == type(item): 
      resultList[-1].append(item) 
     else: 
      resultList.append([item]) 

print(resultList) # [[26], [None, None, None], [31], [None, None], [58], [None], [42], [None, None, None], [79]] 

# now lets interpolate the sublists that contain Nones 
for i, item in enumerate(resultList): 
    if item[0] is not None: 
     continue 

    # this is a bit problematic, what do we do if we have a None at the beginning or at the end? 
    if i == 0 or i + 1 == len(resultList): 
     continue 

    prev_item = resultList[i - 1][-1] 
    next_item = resultList[i + 1][0] 

    difference = next_item - prev_item 
    item_length = len(item) + 1 

    for j, none_item in enumerate(item): 
     item[j] = prev_item + float(j + 1)/item_length * difference 

# flatten the list back 
resultList = [item for sublist in resultList for item in sublist] 

print(resultList) # [26, 27.25, 28.5, 29.75, 31, 40.0, 49.0, 58, 50.0, 42, 51.25, 60.5, 69.75, 79] 

मैं तुम्हें केवल सीखने के लिए या साधारण मामलों के लिए इसका उपयोग के रूप में यह मामलों है जहाँ आप सूचियों शुरुआत या None के साथ समाप्त होने से हैंडल नहीं करता सुझाव देते हैं:

संपूर्णता के लिए

हालांकि यहां आ त्वरित समाधान मैं के साथ आया है

+0

आपके दो उत्तरों प्रदान करने के लिए धन्यवाद! इंटरप। टूल मेरे डेटा सेट को इंटरपोल करने का एक आसान तरीका प्रतीत होता है, लेकिन यह केवल रैखिक है। मुझे एक ऐसी विधि की आवश्यकता है जो दूरी को दूर रखे और वर्गबद्ध भार का उपयोग करे। एक शास्त्रीय आईडीडब्लू-दृष्टिकोण बहुत लंबा रास्ता लेगा, इसलिए मैं अपना विचार लागू करना चाहता था। ऊपरी समाधान मुझे नज़दीक देखने की आवश्यकता है। पहली नज़र में ऐसा लगता है कि यह तेज़ होने वाला नहीं था, लेकिन शायद मुझे वहां कुछ महत्वपूर्ण याद आया। "कोई नहीं" होने वाली पहली या आखिरी वस्तु के बारे में कोई चिंता नहीं - मैंने यह सुनिश्चित किया कि यह कभी नहीं होगा। – offeltoffel

+1

ठीक है, दूसरे टुकड़े के साथ आप इंटरपोलेशन को स्वयं कार्यान्वित कर सकते हैं, बस लूप के लिए आंतरिक संपादित करें :) – mirosval

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

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