Interpolare liniară folosind numpy.interp (Programare, Python, Numpy, Interpolare, Interpolare Liniară)

utilizator1789657 a intrebat.

Am o matrice 1 dimensională A de float care este în mare parte bună, dar câteva dintre valori lipsesc. Datele lipsă sunt înlocuite cu nan(nu este un număr). Trebuie să înlocuiesc valorile lipsă din matrice prin interpolare liniară din valorile bune din apropiere. Deci, de exemplu:

F7(np.array([10.,20.,nan,40.,50.,nan,30.])) 

ar trebui să returneze

np.array([10.,20.,30.,40.,50.,40.,30.]). 

Care este cea mai bună modalitate de a face acest lucru folosind Python?

Orice ajutor ar fi foarte apreciat

Mulțumesc

Comentarii

  • Chiar vă referiți la interpolarea liniară? Sau vă referiți de fapt la medie? — Presupun, de asemenea, că prima și ultima valoare sunt garantate să nu fie NaN? –  > Por mgilson.
  • A fost doar o medie în exemplu. Interpolarea liniară ar trebui de fapt să găsească doar valorile lipsă într-o ecuație liniară. Și da, prima și ultima valoare nu sunt NaN. – user1789657
3 răspunsuri
Fred Foo

Ați putea folosi scipy.interpolate.interp1d:

>>> from scipy.interpolate import interp1d
>>> import numpy as np
>>> x = np.array([10., 20., np.nan, 40., 50., np.nan, 30.])
>>> not_nan = np.logical_not(np.isnan(x))
>>> indices = np.arange(len(x))
>>> interp = interp1d(indices[not_nan], x[not_nan])
>>> interp(indices)
array([ 10.,  20.,  30.,  40.,  50.,  40.,  30.])

EDITARE: mi-a luat ceva timp să-mi dau seama cum se face np.interp funcționează, dar și asta poate face treaba:

>>> np.interp(indices, indices[not_nan], x[not_nan])
array([ 10.,  20.,  30.,  40.,  50.,  40.,  30.])

Comentarii

  • Cred că aș folosi len(x) mai degrabă decât *x.shape. Pare puțin mai explicit, deoarece oricum facem doar 1D (și asta nu se generalizează la mai multe dimensiuni) – dar +1 pentru o soluție de interpolare funcțională. –  > Por mgilson.
  • În loc să generăm np.arange(len(x)) de două ori, de ce să nu o facem doar o singură dată și să stocăm rezultatul? De asemenea, nu cred că aveți nevoie de scipy pentru acest lucru. np.interp se pare că ar face același lucru în acest scenariu –  > Por mgilson.
  • @mgilson: ai avut dreptate de trei ori. Mulțumesc, am actualizat răspunsul. –  > Por Fred Foo.
root

Eu aș merge cu pandas. O abordare minimalistă, cu o linie de un singur rând:

from pandas import *
a=np.array([10.,20.,nan,40.,50.,nan,30.])
Series(a).interpolate()   

Out[219]:
0    10
1    20
2    30
3    40
4    50
5    40
6    30

Sau, dacă doriți să o păstrați ca o matrice:

Series(a).interpolate().values

Out[221]:
array([ 10.,  20.,  30.,  40.,  50.,  40.,  30.])

Comentarii

  • @larsmans — tocmai voiam să sugerez .values , care, de asemenea, returnează un array 🙂 –  > Por root.
  • Am văzut, mi-am șters comentariul. Pandas este încă pe lista „bibliotecilor de învățat” 🙂 –  > Por Fred Foo.
Кириллл Солодских

Pentru a nu crea un nou obiect Series sau noi elemente în Series de fiecare dată când doriți să interpolați date, utilizați RedBlackPy. A se vedea exemplul de cod de mai jos:

import redblackpy as rb

# we do not include missing data
index = [0,1,3,4,6]
data = [10,20,40,50,30]
# create Series object
series = rb.Series(index=index, values=data, dtype='float32',
                   interpolate='linear')

# Now you have access at any key using linear interpolation
# Interpolation does not creates new items in Series
print(series[2]) # prints 30
print(series[5]) # prints 40
# print Series and see that keys 2 and 5 do not exist in series
print(series)

Ultima ieșire este următoarea:

Series object Untitled
0: 10.0
1: 20.0
3: 40.0
4: 50.0
6: 30.0