Ho una lista di lunghezza 2016, ma solo 242 contengono dati, il resto è impostato su Nessuno. Il mio obiettivo è quello di interpolare tra i valori per colmare tutte le lacune con una semplice forma di IDW (ponderazione inversa della distanza). Quindi il compito del mio script è:Il modo più efficace per trovare i vicini nell'elenco
- iterare su tutte le voci di myList
- Se il myList contiene un valore (cioè non Nessuno), basta copiarlo
- Se si trova un " Nessuno "nella lista, ottenere la posizione/il valore del vicino sinistro e destro calcolando la distanza da tutti gli elementi in myList
- Calcolare un valore interpolato per il divario da entrambi i vicini (più sono lontani, minore sarà il peso che avranno)
Supponiamo di avere una lista più piccola di soli 14 articoli (5 quelli validi):
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]
che sto facendo che per molti molti insiemi di dati. Ho scoperto che questo metodo richiede circa 0,59 secondi per set di dati. Quello che mi infastidisce è il fatto che la mia lista è tutto in ordine, ma mi basteranno solo 2 valori. Quindi il 99% delle distanze è calcolato per niente. Questo mi ha portato a tentare due: fermare l'iterazione dopo ij diventa negativo, perché poi, ovviamente, ha incontrato i valori più vicini:
così invece della lista di comprensione:
distance = [i - j for j in range(len(myList)) if not myList[j] is None]
faccio un corretto ciclo for che ho lasciato dopo distanze passano zero e quindi diventano più grandi ancora:
dist = []
for j in range(len(myList)):
if not myList[j] is None:
dist.append(i-j)
if i-j < 0: break
Con questo metodo ho potuto scendere a 0.38sec per set di dati. Quando si itera su tutti gli elementi in myList, questo secondo metodo è rapido all'inizio (l'elemento viene colpito dopo il 2 °, 3 °, 4 ° ... e si chiude immediatamente), ma non c'è alcun miglioramento per gli ultimi elementi, poiché l'iterazione inizia sempre a j = 0.
Mi chiedo se riesci a pensare a un modo più rapido per trovare i due vicini di un numero specifico in un set di dati, senza dover controllare TUTTE le distanze e solo prendendo il più grande negativo e piccolo positivo.
Inoltre, sono abbastanza nuovo per Python, quindi per favore fatemi sapere se trovate altre espressioni non-pythonic nel mio script. Grazie mille!
Numpy fornisce alcuni algoritmi del vicino più vicino che potresti dare un'occhiata a [loro] (http://docs.scipy.org/doc/scipy/reference/spatial.html#nearest-neighbor-queries) – albert
E lì è la funzione 'pandas.Series.interpolate' che fa tutto questo. – pacholik
Che ne dici di una risposta alla domanda [Interpolazione con distanza interpolata (IDW) con Python] (http://stackoverflow.com/questions/3104781/inverse-distance-weighted-idw-interpolation-with-python)? – ojdo