Интерполяция, игнорирующая нулевые значения в массиве - Python

У меня есть два массива одинаковой длины

x = array([-243., -242., -241., -240., -239., -238., -237., -236., -235.,
       -234., -233., -232., -231., -230., -229., -228., -227., -226.,
       -225., -224., -223., -222., -221., -220., -219., -218., -217.,
       -216., -215., -214., -213., -212., -211., -210., -209., -208.,
       -207., -206., -205., -204., -203., -202., -201., -200., -199.,
       -198., -197., -196., -195., -194., -193., -192., -191., -190.,
       -189., -188., -187., -186., -185., -184., -183., -182., -181.,
       -180., -179., -178., -177., -176., -175., -174., -173., -172.,
       -171., -170., -169., -168., -167., -166., -165., -164., -163.,
       -162., -161., -160., -159., -158., -157., -156., -155., -154.,
       -153., -152., -151., -150., -149., -148., -147., -146., -145.,
       -144., -143., -142., -141., -140., -139., -138., -137., -136.,
       -135., -134., -133., -132., -131., -130., -129., -128., -127.,
       -126., -125., -124., -123., -122., -121., -120., -119., -118.,
       -117., -116., -115., -114., -113., -112., -111., -110., -109.,
       -108., -107., -106., -105., -104., -103., -102., -101., -100.,
        -99.,  -98.,  -97.,  -96.,  -95.,  -94.,  -93.,  -92.,  -91.,
        -90.,  -89.,  -88.,  -87.,  -86.,  -85.,  -84.,  -83.,  -82.,
        -81.,  -80.,  -79.,  -78.,  -77.,  -76.,  -75.,  -74.,  -73.,
        -72.,  -71.,  -70.,  -69.,  -68.,  -67.,  -66.,  -65.,  -64.,
        -63.,  -62.,  -61.,  -60.,  -59.,  -58.,  -57.,  -56.,  -55.,
        -54.,  -53.,  -52.,  -51.,  -50.,  -49.,  -48.,  -47.,  -46.,
        -45.,  -44.,  -43.,  -42.,  -41.,  -40.,  -39.,  -38.,  -37.,
        -36.,  -35.,  -34.,  -33.,  -32.,  -31.,  -30.,  -29.,  -28.,
        -27.,  -26.,  -25.,  -24.,  -23.,  -22.,  -21.,  -20.,  -19.,
        -18.,  -17.,  -16.,  -15.,  -14.,  -13.,  -12.,  -11.,  -10.,
         -9.,   -8.,   -7.,   -6.,   -5.,   -4.,   -3.,   -2.,   -1.,
         -0.,    0.,    1.,    2.,    3.,    4.,    5.,    6.,    7.,
          8.,    9.,   10.,   11.,   12.,   13.,   14.,   15.,   16.,
         17.,   18.,   19.,   20.,   21.,   22.,   23.,   24.,   25.,
         26.,   27.,   28.,   29.,   30.,   31.,   32.,   33.,   34.,
         35.,   36.,   37.,   38.,   39.,   40.,   41.,   42.,   43.,
         44.,   45.,   46.,   47.,   48.,   49.,   50.,   51.,   52.,
         53.,   54.,   55.,   56.,   57.,   58.,   59.,   60.,   61.,
         62.,   63.,   64.,   65.,   66.,   67.,   68.,   69.,   70.,
         71.,   72.,   73.,   74.,   75.,   76.,   77.,   78.,   79.,
         80.,   81.,   82.,   83.,   84.,   85.,   86.,   87.,   88.,
         89.,   90.,   91.,   92.,   93.,   94.,   95.,   96.,   97.,
         98.,   99.,  100.,  101.,  102.,  103.,  104.,  105.,  106.,
        107.,  108.,  109.,  110.,  111.,  112.,  113.,  114.,  115.,
        116.,  117.,  118.,  119.,  120.,  121.,  122.,  123.,  124.,
        125.,  126.,  127.,  128.,  129.,  130.,  131.,  132.,  133.,
        134.,  135.,  136.,  137.,  138.,  139.,  140.,  141.,  142.,
        143.,  144.,  145.,  146.,  147.,  148.,  149.,  150.,  151.,
        152.,  153.,  154.,  155.,  156.,  157.,  158.,  159.,  160.,
        161.,  162.,  163.,  164.,  165.,  166.,  167.,  168.,  169.,
        170.,  171.,  172.,  173.,  174.,  175.,  176.,  177.,  178.,
        179.,  180.,  181.,  182.,  183.,  184.,  185.,  186.,  187.,
        188.,  189.,  190.,  191.,  192.,  193.,  194.,  195.,  196.,
        197.,  198.,  199.,  200.,  201.,  202.,  203.,  204.,  205.,
        206.,  207.,  208.,  209.,  210.,  211.,  212.,  213.,  214.,
        215.,  216.,  217.,  218.,  219.,  220.,  221.,  222.,  223.,
        224.,  225.,  226.,  227.,  228.,  229.,  230.,  231.,  232.,
        233.,  234.,  235.,  236.,  237.,  238.,  239.,  240.,  241.,
        242.,  243.])

 y = array([  0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   8.31593344e-02,
     2.35439791e-01,   9.96024791e-01,   2.05616777e+00,
     7.18482061e+00,   1.88705079e+01,   2.95964175e+01,
     7.67566181e+01,   1.00520725e+02,   1.50101258e+02,
     1.30495335e+02,   7.38818649e+01,   7.88215800e+01,
     8.27782533e+01,   8.54715249e+01,   0.00000000e+00,
     0.00000000e+00,   8.66810877e+01,   0.00000000e+00,
     0.00000000e+00,   8.62917273e+01,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   8.43340655e+01,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     8.10109967e+01,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   7.67001996e+01,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   7.19263508e+01,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   6.73025361e+01,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     6.34476840e+01,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     6.08936791e+01,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     6.00000000e+01,   6.00000000e+01,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   6.08936791e+01,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   6.34476840e+01,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   6.73025361e+01,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     7.19263508e+01,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     7.67001996e+01,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   8.10109967e+01,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00,   8.43340655e+01,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     8.62917273e+01,   0.00000000e+00,   0.00000000e+00,
     8.66810877e+01,   0.00000000e+00,   0.00000000e+00,
     8.54715249e+01,   8.27782533e+01,   7.88215800e+01,
     7.38818649e+01,   1.30495335e+02,   1.50101258e+02,
     1.00520725e+02,   7.67566181e+01,   2.95964175e+01,
     1.88705079e+01,   7.18482061e+00,   2.05616777e+00,
     9.96024791e-01,   2.35439791e-01,   8.31593344e-02,
     0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
     0.00000000e+00,   0.00000000e+00])

построение графика зависимости x от доходности

xy график массивов без интерполяции

Мой вопрос в том, как я могу интерполировать y, чтобы график игнорировал нулевые значения и давал плавную кривую.

Результат должен выглядеть примерно так (оси игнорировать): кривая должна быть плавной, игнорируя любые каналы x, где соответствующие  значение y равно нулю

Ваше здоровье


person smashbro    schedule 03.01.2014    source источник
comment
Можете ли вы опубликовать SSCCE? Так что нам легче вам помочь.   -  person Christian    schedule 03.01.2014
comment
Замените нули на NaN и используйте это метод stackoverflow.com/questions/6518811/ (см. принятый ответ)   -  person Steinar Lima    schedule 03.01.2014


Ответы (3)


Используя numpy.where:

indice = numpy.where(y != 0)
plot(x[indice], y[indice])

или используя numpy.nonzero:

indice = numpy.nonzero(y) # OR y.nonzero()
plot(x[indice], y[indice])

введите описание изображения здесь


ОБНОВЛЕНИЕ

интерполяция с использованием scipy.interpolate.interp1d:

from scipy.interpolate import interp1d

indice, = y.nonzero()
start, stop = indice[0], indice[-1]+1
f = interp1d(x[indice], y[indice])
y[start:stop] = f(x[start:stop])
plot(x, y)
person falsetru    schedule 03.01.2014
comment
возможно, немного быстрее использовать y.nonzero(), а не where - person chthonicdaemon; 03.01.2014
comment
@chthonicdaemon, Спасибо за комментарий. Я добавил код, который nonzero. - person falsetru; 03.01.2014
comment
Я думал об этом, но мне нужно, чтобы массивы были одинаковой длины. Массив x - это скорость, при которой я пытаюсь выполнить выборку со скоростью 1 км / с, поэтому я не могу ее изменить. - person smashbro; 03.01.2014
comment
@smashbro, я обновил ответ, чтобы использовать scipy.interpolate.interp1d. - person falsetru; 03.01.2014
comment
Большое спасибо, это именно то, что я искал. Мне бы очень помогло понимание, если бы вы могли добавить один или два комментария, просто чтобы объяснить, что на самом деле делает код. - person smashbro; 03.01.2014
comment
@smashbro, scipy.interpolate.interp1d возвращают функцию, которую можно использовать для получения приблизительных значений y. start, stop использовался для исключения начальных и конечных нулей. - person falsetru; 03.01.2014

Используйте маску:

from numpy import interp
plot( x, interp(x, x[y!=0], y[y!=0]) )

Результат выглядит так: введите описание изображения здесь

interp возвращает значения для y в x путем интерполяции между значениями x[y!=0], y[y!=0]. Это задокументировано здесь. y!=0 - это логический вектор, который истинен, когда y не равен нулю, и используется здесь как выбор маска.

person John1024    schedule 03.01.2014
comment
Я думал об этом, но мне нужно, чтобы массивы были одинаковой длины. Массив x - это скорость, при которой я пытаюсь выполнить выборку со скоростью 1 км / с, поэтому я не могу ее изменить. - person smashbro; 03.01.2014

Я пробовал это, не так гладко, как вы хотели, но может помочь.

Код:

new_x = []
new_y = []
for i in range(len(y)):
    if y[i] != 0:
        new_x.append(x[i])
        new_y.append(y[i])
plt.plot(new_x, new_y)
plt.show()

Результат:

введите описание изображения здесь

person Christian    schedule 03.01.2014