Векторизованное число ежедневных длинных последовательных полос - PullRequest
4 голосов
/ 10 июля 2019

Для оценки ежедневных самых длинных последовательных периодов работы электростанции я должен оценить самую длинную полосу в день , что означает, что каждый день рассматривается как отдельный таймфрейм.

Так скажемУ меня есть выходная мощность в кадре данных df:

df = pd.Series(
    data=[
        *np.zeros(4), *(np.full(24*5, 19.5) + np.random.rand(24*5)), 
        *np.zeros(4), *(np.full(8, 19.5) + np.random.rand(8)), 
        *np.zeros(5), *(np.full(24, 19.5) + np.random.rand(24)), 
        *np.zeros(27), *(np.full(24, 19.5) + np.random.rand(24))], 
    index=pd.date_range(start='2019-07-01 00:00:00', periods=9*24, freq='1h'))

И «мощность отсечки» равна 1 (все, что ниже, считается отключенным).Я использую это, чтобы замаскировать значения «on», сдвинуть и сравнить маску с собой, чтобы подсчитать количество последовательных groups.Наконец, я группирую groups по дням года в индексе и подсчитываю ежедневные последовательные значения consec_group:

mask = df > 1
groups = mask.ne(mask.shift()).cumsum()
consec_group = groups[mask].groupby(groups[mask].index.date).value_counts()

Что дает:

consec_group
Out[3]: 
2019-07-01  2    20
2019-07-02  2    24
2019-07-03  2    24
2019-07-04  2    24
2019-07-05  2    24
2019-07-06  4     8
            2     4
            6     3
2019-07-07  6    21
2019-07-09  8    24
dtype: int64

Но я бы хотел, чтобы максимальное значение каждой последовательной дневной серии и даты без времени выполнения отображались с нулями, как в 2019-07-08 7 0.Смотрите ожидаемый результат:

2019-07-01    20
2019-07-02    24
2019-07-03    24
2019-07-04    24
2019-07-05    24
2019-07-06     8
2019-07-07    21
2019-07-08     0
2019-07-09    24
dtype: int64

Любая помощь будет оценена!

Ответы [ 2 ]

4 голосов
/ 10 июля 2019

Сначала удалите второй уровень с помощью Series.reset_index, отфильтруйте вторые дублированные значения путем обратного вызова с Series.asfreq - это работает, потому что .value_counts sort Series:

consec_group = (consec_group.reset_index(level=1, drop=True)[lambda x: ~x.index.duplicated()]
                            .asfreq('d', fill_value=0))
print (consec_group)

Или решение с GroupBy.first:

consec_group = (consec_group.groupby(level=0)
                            .first() 
                            .asfreq('d', fill_value=0))

print (consec_group)
2019-07-01    20
2019-07-02    24
2019-07-03    24
2019-07-04    24
2019-07-05    24
2019-07-06     8
2019-07-07    21
2019-07-08     0
2019-07-09    24
Freq: D, dtype: int64
1 голос
/ 10 июля 2019

Хорошо, я думаю, я был слишком близко к финишной черте, чтобы увидеть ответ ... Похоже, я уже решил сложную часть.
Так что сразу после публикации вопроса я протестировал max с помощью *Аргумент 1003 * вместо level=1, и это было решением:

max_consec_group = consec_group.max(level=0).asfreq('d', fill_value=0)

Спасибо в Jezrael за asfreq часть!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...