У меня есть датафрейм Python с почасовыми значениями за январь 2015 года, за исключением того, что в некоторых часах отсутствуют индекс и значения обоих. В идеале информационный кадр со столбцами с именами «даты» и «значения» должен иметь 744 строки. Тем не менее, он случайно пропустил 10 часов и, следовательно, имеет только 734 строки. Я хочу интерполировать пропущенные часы в месяце, чтобы создать нужный фрейм данных с 744 «датами» и 744 «значениями».

Редактировать:

Я новичок в Python, поэтому я борюсь с реализацией этой идеи:

  • Создайте фрейм данных с первым столбцом за все часы в январе 2015 г.
  • Создайте второй столбец того же размера, что и первый из NAN
  • Заполните второй столбец доступными значениями, поэтому в пропущенных часах есть NAN
  • Используйте функцию интерполяции панды

Edit2 :

Я искал подсказку для фрагментов кода. Основываясь на предложении ниже, я смог создать следующий код, но он не может заполнить значения, которые являются нулями в начале месяца, то есть для часов с 1 по 5 1 января.

import panda as pd
st_dt   =   '2015-01-01'
en_dt   =   '2015-01-31'
DateTimeHour =   pd.date_range( pd.Timestamp( st_dt ).date(), pd.Timestamp(    
en_dt ).date(), freq='H')
Pwr.index    =   pd.DatetimeIndex(Pwr.index) #Pwr is the original dataframe
Pwr          =   Pwr.reindex( DateTimeHour, fill_value = 0 )
Pwr2         =   pd.Series( Pwr.values )
Pwr2.interpolate( imit_direction='both' )
0
Zanam 18 Дек 2015 в 22:28

3 ответа

Лучший ответ

Используйте df.asfreq расширить DataFrame, чтобы иметь почасовую частоту. NaN вставляется для пропущенных значений:

df = df.asfreq('H')

Затем используйте df.interpolate заменить NaN (линейно) интерполированными значениями на основе DatetimeIndex и ближайших не-NaN значений:

df = df.interpolate(method='time')

Например,

import numpy as np
import pandas as pd

N, M = 744, 734
index = pd.date_range('2015-01-01', periods=N, freq='H')
idx = np.random.choice(np.arange(N), M, replace=False)
idx.sort()
index = index[idx]

# This creates a toy DataFrame with 734 non-null rows:
df = pd.DataFrame({'values': np.random.randint(10, size=(M,))}, index=index)

# This expands the DataFrame to 744 rows (10 null rows):
df = df.asfreq('H')

# This makes `df` have 744 non-null rows:
df = df.interpolate(method='time')
1
unutbu 18 Дек 2015 в 20:05

Общая интерполяция следующая:

Если ключ выходит:

  • Вернуть значение

Еще :

  • Найдите первый ключ до и после требуемого ключа, найдите расстояние (которое вы можете определить, используя желаемую метрику) для обоих ключей и возьмите средневзвешенное значение, взвешенное по расстояниям между клавишами (близок - это более высокий вес).
0
Hidde 18 Дек 2015 в 19:35

То, что вы хотите, требует сочетания этой техники: Добавить недостающие даты в фрейм данных панд

И функция панд pandas.Series.interpolate. Из того, что вы сказали, вариант «линейный» это то, что вы хотите.

EDIT :
Интерполяция не будет работать, если у вас отсутствуют точки данных в самом начале временного ряда. Одна идея состоит в том, чтобы использовать pandas.Series.fillna с 'backfill' после интерполяции. Кроме того, не устанавливайте fill_value в 0, если вы вызываете переиндексацию

1
Community 23 Май 2017 в 12:23