У меня есть временной ряд, где один из столбцов содержит в основном NaN. Фрейм данных довольно большой, поэтому обработка всех этих NaN становится бременем. Если я просто отброшу их все, графики будут полностью перепутаны с интерполяцией между оставшимися точками данных.
Вот краткий пример того, что у меня есть:
v x
0.0000 0.000000 NaN
0.0002 0.062791 NaN
0.0004 0.125333 NaN
0.0006 0.187381 95.0
0.0008 0.248690 NaN
0.0010 0.309017 NaN
0.0012 0.368125 NaN
0.0014 0.425779 88.0
0.0016 0.481754 85.0
0.0018 0.535827 91.0
0.0020 0.587785 NaN
0.0022 0.637424 NaN
0.0024 0.684547 NaN
0.0026 0.728969 99.0
...
и чего я хочу добиться:
v x
0.0004 0.125333 NaN
0.0006 0.187381 95.0
0.0012 0.368125 NaN
0.0014 0.425779 88.0
0.0016 0.481754 85.0
0.0018 0.535827 91.0
0.0024 0.684547 NaN
0.0026 0.728969 99.0
...
Итерация по строкам - не вариант, так как это будет медленным, но я не могу придумать разумного подхода. Есть идеи?
Пример набора данных (довольно короткий) для работы с:
import pandas as pd
import numpy as np
f=50
Tmax = 1
fs= 5000
df = pd.DataFrame(index=np.arange(0, Tmax, 1/fs), data={'x':np.random.randint(0,100, size=int(fs*Tmax))})
df['v'] = np.sin(2*np.pi*f*df.index)
# Most of "x" is NaN
df.loc[df['x']<75, 'x'] = np.NaN
Всего 2 ответа
Используйте boolean indexing
со сравнением по Series.shift
ed и Series.notna
и цепочкой по |
для побитового ИЛИ:
df = df[df.x.shift(-1).notna() | df.x.notna()]
print (df)
v x
0.0004 0.125333 NaN
0.0006 0.187381 95.0
0.0012 0.368125 NaN
0.0014 0.425779 88.0
0.0016 0.481754 85.0
0.0018 0.535827 91.0
0.0024 0.684547 NaN
0.0026 0.728969 99.0
Создайте новую переменную temp, используя метод shift для x.
df['temp'] = df.x.shift(-1)
Затем отфильтруйте строки, где x или temp не равны NULL.
df[(~df.x.isnull())|(~df.temp.isnull())]
Поскольку этот подход использует встроенные функции и фильтрацию, а не циклы, он должен быть быстрее.