2016-12-20 1 views
6

У меня есть набор данных:Удалить значения NaN из dataframe без fillna или интерполировать

  367235 419895 992194 
1999-01-11 8 5 1 
1999-03-23 NaN 4 NaN 
1999-04-30 NaN NaN 1 
1999-06-02 NaN 9 NaN 
1999-08-08 2 NaN NaN 
1999-08-12 NaN 3 NaN 
1999-08-17 NaN NaN 10 
1999-10-22 NaN 3 NaN 
1999-12-04 NaN NaN 4 
2000-03-04 2 NaN NaN 
2000-09-29 9 NaN NaN 
2000-09-30 9 NaN NaN 

Когда я сюжет его, используя plt.plot(df, '-o') я получаю это:

output from plotting dataframe

Но то, что я хотел бы это для данных по каждому столбцу, который должен быть подключен по линии:

desired output from plotting dataframe

Я понимаю, что matplotlib не связывает данные, разделенные значениями NaN. Я рассмотрел все варианты here для работы с отсутствующими данными, но все они существенно исказили бы данные в кадре данных. Это связано с тем, что каждое значение в кадре данных представляет собой инцидент; если я попытаюсь заменить NaN скалярными значениями или использовать опцию интерполяции, я получаю кучу точек, которые на самом деле не находятся в моем наборе данных. Вот что интерполировать выглядит следующим образом:

df_wanted2 = df.apply(pd.Series.interpolate)

enter image description here

Если я пытаюсь использовать dropna я потеряю все строки \ столбцов из dataframe, и эти строки держать ценные данные.

Кто-нибудь знает, как подключить мои точки? Я подозреваю, что мне нужно извлечь отдельные массивы из фреймворка и зарисовать их, как это дается here, но это похоже на большую работу (и мой фактический размер данных намного больше.) У кого-нибудь есть решение?

ответ

11

использования interpolate метода с параметром 'index'

df.interpolate('index').plot(marker='o') 

enter image description here

альтернативного ответ

plot после iteritems

for _, c in df.iteritems(): 
    c.dropna().plot(marker='o') 

enter image description here


дополнительного кредит
только интерполировать от первого действительного индекса последнего допустимого индекса для каждого столбца

for _, c in df.iteritems(): 
    fi, li = c.first_valid_index(), c.last_valid_index() 
    c.loc[fi:li].interpolate('index').plot(marker='o') 

enter image description here

+0

Второй ответ отлично поработал, потому что линии не дошли до конца сюжета - огромное спасибо! – oymonk

+0

IMO, этот ответ был бы улучшен, если бы вы перенесли «альтернативный ответ» первым (или даже сделали его единственным). Другие два подхода приводят к ошибочным графикам, поскольку они добавляют очевидные точки данных, которые фактически не присутствуют в данных ОП. –

+0

@IlmariKaronen хорошие моменты. Я отредактирую позже и уточню. Thx для обратной связи – piRSquared

4

Попробуйте перебор с apply, а затем внутри функций применяются уронить недостающие значения

def make_plot(s): 
    s.dropna().plot() 

df.apply(make_plot) 
+0

Спасибо. Выберите ответ @pirsquared, так как лучше и полнее –

3

В качестве альтернативы можно аутсорсинг NaN обработки на графике libary Plotly, используя его connectgaps функцию.

import plotly 
import pandas as pd 

txt = """367235 419895 992194 
1999-01-11 8 5 1 
1999-03-23 NaN 4 NaN 
1999-04-30 NaN NaN 1 
1999-06-02 NaN 9 NaN 
1999-08-08 2 NaN NaN 
1999-08-12 NaN 3 NaN 
1999-08-17 NaN NaN 10 
1999-10-22 NaN 3 NaN 
1999-12-04 NaN NaN 4 
2000-03-04 2 NaN NaN 
2000-09-29 9 NaN NaN 
2000-09-30 9 NaN NaN""" 

data_points = [line.split(' ') for line in txt.splitlines()[1:]] 
df = pd.DataFrame(data_points) 

data = list() 
for i in range(1, len(df.columns)): 
    data.append(plotly.graph_objs.Scatter(
     x = df.iloc[:,0].tolist(), 
     y = df.iloc[:,i].tolist(), 
     mode = 'line', 
     connectgaps = True 
    )) 

fig = dict(data=data) 
plotly.plotly.sign_in('user', 'token') 
plot_url = plotly.plotly.plot(fig) 

enter image description here

Смежные вопросы