Заполните нули из данных прошлой недели (168 индексов ранее) в кадре данных pandas - PullRequest
0 голосов
/ 31 января 2020

У меня есть данные об использовании электроэнергии. Во время отключения питания данные равны '0'. Я хочу заменить эти 0 на данные того же времени за последнюю неделю. Что на 168 индексов вперед или назад в наборе данных.

В приведенном ниже коде я сохраняю индекс всех нулей. Запуск al oop, который поместит значение, которое находится на 168 индексов вперед, в наборе данных с текущим индексом.

Index_Zero = data[data["Total"]==0].index.to_list() #Output = list of indexes where all the zeros lie

print(Index_Zero[0]) #Output = 2

for i in Index_Zero:
    data.loc[(Index_Zero[i]), 'Total']=data.loc[(Index_Zero[i+168]), 'Total']

Кроме того, если я напечатаю

data.loc[(Index_Zero[0]), 'Total']=data.loc[(Index_Zero[2]), 'Total']
print(data.loc[(Index_Zero[0]), 'Total'])
Output: 0.0

DataSet:

           Date         Time     Total
0     23-Jan-2019  12:00:00 AM  18343.00
1     23-Jan-2019  01:00:00 AM  18188.00
2     23-Jan-2019  02:00:00 AM      0.00
3     23-Jan-2019  03:00:00 AM  23394.00
4     23-Jan-2019  04:00:00 AM  20037.00

Ответы [ 3 ]

0 голосов
/ 31 января 2020

Я думаю, более естественным решением является:

  • Установить для индекса значение "true" datetime , полученное из Date и Время столбцы.
  • Запуск al oop по индексам строк с Total == 0 .
    • Получить значение из строки с индексом 1 неделю назад.
    • Сохранить это значение как Всего в строке с текущим индексом.
  • Наконец сбросьте индекс до того, что был раньше.

Для этого выполните:

df.set_index(pd.to_datetime(df.Date + ' ' + df.Time), inplace=True)
for ind in df[df.Total.eq(0)].index:
    df.loc[ind, 'Total'] = df.loc[ind - pd.Timedelta('1W'), 'Total']
df.reset_index(drop=True, inplace=True)

Обратите внимание, что l oop должен быть основан только на индексах, а не на полных строках. Причина в том, что отключение питания может произойти в определенный день недели и час, например, через 2 (или более) недели подряд.

Так что oop основано на полных строках ( для ... в df [df] .Total.eq (0)]. Iterrows (): ) будет всегда извлекать исходных итоговых значений (обновление не будет происходить за одну неделю при обработке строки на следующую неделю (при условии, что обе эти строки содержали изначально 0 )).

Еще одно замечание

При условии, что ваши строки упорядочены по Дата / Время , ваш исходный код должен:

  • См. Текущий индекс минус 168 (одна неделя до , а не после ).
  • Упомянутое вычитание od 168 должно быть сделано из текущего индекса ( Index_Zero [i] ).

Таким образом, этот фрагмент кода должен быть на самом деле data.loc [(Index_Zero [i] - 168), 'Total'] .

Но мое решение устойчив к любым ошибкам петь строки в DataFrame, поэтому я советую принять решение.

0 голосов
/ 05 февраля 2020

Проблема была в диапазоне для l oop. Итерация за пределами списка.

Index_Zero = data[data["Total"]==0].index.to_list()
for items in range(0, len(Index_Zero)-1):
    data.loc[(Index_Zero[items]), 'Total'] = data.loc[(items+168), 'Total']

0 голосов
/ 31 января 2020

Вот что я думаю, это проблема. Вы заменяете значение data.loc[(Index_Zero[i]), 'Total'] как значение индекса (i + 168) в списке Index_zero, который всегда равен 0. (Вы поддерживали список именно для этого). Я думаю, что это невинная ошибка. Измените свой код на этот

Index_Zero = data[data["Total"]==0].index.to_list() #Output = list of indexes where all the zeros lie

print(Index_Zero[0]) #Output = 2

for i in Index_Zero:
    data.loc[(Index_Zero[i]), 'Total']=data.loc[(i+168), 'Total']
...