Заполнение NaN с помощью «ffill» и «интерполировать» в зависимости от времени дня появления NaN в Python - PullRequest
0 голосов
/ 10 декабря 2018

Я хочу заполнить NaN в df, используя «среднее» и «интерполировать» в зависимости от того, в какое время дня происходит NaN.Как вы можете видеть ниже, первый NaN происходит в 6 часов утра, а второй NaN в 8 часов утра.

02/03/2016 05:00    8
02/03/2016 06:00    NaN
02/03/2016 07:00    1
02/03/2016 08:00    NaN
02/03/2016 09:00    3

Мой ДФ состоит из тысячи дней.Я хочу применить 'ffill' для любого NaN, возникшего до 7 часов утра, и применить 'интерполировать' для тех, которые происходят после 7 часов утра.Мои данные с 6 утра до 6 вечера.

Моя попытка:

df_imputed = (df.between_time("00:00:00", "07:00:00", include_start=True, include_end=False)).ffill()
df_imputed = (df.between_time("07:00:00", "18:00:00", include_start=True, include_end=True)).interpolate()   

Но она сократила мою df до назначенных периодов времени, а не заполняла NaN, как я хочу.

Редактировать: моя df содержитоколо 400 столбцов, поэтому процедура будет применяться ко всем столбцам.

1 Ответ

0 голосов
/ 10 декабря 2018

Исходный вопрос: одна серия значений

Вы можете определить логическую серию в соответствии с вашим состоянием, затем interpolate или ffill в зависимости от ситуации с помощьюnumpy.where:

# setup
df = pd.DataFrame({'date': ['02/03/2016 05:00', '02/03/2016 06:00', '02/03/2016 07:00',
                            '02/03/2016 08:00', '02/03/2016 09:00'],
                   'value': [8, np.nan, 1, np.nan, 3]})
df['date'] = pd.to_datetime(df['date'])

# construct Boolean switch series
switch = (df['date'] - df['date'].dt.normalize()) > pd.to_timedelta('07:00:00')

# use numpy.where to differentiate between two scenarios
df['value'] = np.where(switch, df['value'].interpolate(), df['value'].ffill())

print(df)

                 date  value
0 2016-02-03 05:00:00    8.0
1 2016-02-03 06:00:00    8.0
2 2016-02-03 07:00:00    1.0
3 2016-02-03 08:00:00    2.0
4 2016-02-03 09:00:00    3.0

Обновленный вопрос: несколько серий значений

С помощью столбцов с несколькими значениями вы можете настроить вышеуказанное решение, используя pd.DataFrame.where и iloc.Или вместо iloc вы можете использовать loc или другие средства (например, filter) выбора столбцов:

# setup
df = pd.DataFrame({'date': ['02/03/2016 05:00', '02/03/2016 06:00', '02/03/2016 07:00',
                            '02/03/2016 08:00', '02/03/2016 09:00'],
                   'value': [8, np.nan, 1, np.nan, 3],
                   'value2': [3, np.nan, 2, np.nan, 6]})
df['date'] = pd.to_datetime(df['date'])

# construct Boolean switch series
switch = (df['date'] - df['date'].dt.normalize()) > pd.to_timedelta('07:00:00')

# use numpy.where to differentiate between two scenarios
df.iloc[:, 1:] = df.iloc[:, 1:].interpolate().where(switch, df.iloc[:, 1:].ffill())

print(df)

                 date  value  value2
0 2016-02-03 05:00:00    8.0     3.0
1 2016-02-03 06:00:00    8.0     3.0
2 2016-02-03 07:00:00    1.0     2.0
3 2016-02-03 08:00:00    2.0     4.0
4 2016-02-03 09:00:00    3.0     6.0
...