Пандам не удается отфильтровать пустые группы с помощью DataFrameGroupBy.filter - PullRequest
0 голосов
/ 05 февраля 2019

Я группирую фрейм данных с индексом даты и времени в интервале 10 минут.Затем я хочу проверить длину каждого сегмента и сбросить сегменты с количеством элементов меньше максимального.

Однако Groupby продолжает создавать пустую группу, которая не содержит какого-либо элемента и поэтомуне удаляется.

Посмотрите на код ниже

import pandas as pd
import numpy as np
import datetime as dt

"Generate test dataframe"
rng = pd.date_range('2018-11-26 16:17:43.510000', periods=90000, freq='0.04S')
df = pd.DataFrame({'a':np.random.randn(len(rng)),'b':np.random.randn(len(rng))}, index=rng)

"Set interval and start time of the buckets"
interval = dt.timedelta(minutes=10)
t0 = df.index[0]
base = t0.minute + (t0.second +t0.microsecond/1e6)/60

"Group df"
groups = df.groupby(pd.Grouper(freq=interval, base=base))

print(len(groups)) 
#7

print(groups.size())

#2018-11-26 16:17:43.510    15000
#2018-11-26 16:27:43.510    15000
#2018-11-26 16:37:43.510    15000
#2018-11-26 16:47:43.510    15000
#2018-11-26 16:57:43.510    15000
#2018-11-26 17:07:43.510    15000
#2018-11-26 17:17:43.510        0 <- I want to remove this group

"Remove all buckets with a lower number of samples"
maxSize = max(groups.size())
def ismaxlen(x):
    print(len(x) == maxSize)
    return len(x) == maxSize

df = groups.filter(ismaxlen) #Prints 6 times True and one time False
                             #This should have removed the last group!
"Group again data"
groups = df.groupby(pd.Grouper(freq=interval, base=base))

print(len(groups)) 
#Prints again 7!! The 7th ghost group is still there

print(groups.size())

#2018-11-26 16:17:43.510    15000
#2018-11-26 16:27:43.510    15000
#2018-11-26 16:37:43.510    15000
#2018-11-26 16:47:43.510    15000
#2018-11-26 16:57:43.510    15000
#2018-11-26 17:07:43.510    15000
#2018-11-26 17:17:43.510        0  <- This group is still here



#Some more weirdness...

print(groups.groups)

#{Timestamp('2018-11-26 16:17:43.510000'): 15000,
# Timestamp('2018-11-26 16:27:43.510000'): 30000,
# Timestamp('2018-11-26 16:37:43.510000'): 45000,
# Timestamp('2018-11-26 16:47:43.510000'): 60000,
# Timestamp('2018-11-26 16:57:43.510000'): 75000,
# Timestamp('2018-11-26 17:07:43.510000'): 90000, <-
# Timestamp('2018-11-26 17:17:43.510000'): 90000} <-last two groups ends at the same index!

print(df.index[-1])
#2018-11-26 17:17:43.470000
# Last data has an index < than last group. Last group should not even exist! 
#Why is a group starting at 17:43.51 created if the last sample is at 17:43.470000

print(len(groups.indices)) 
#Prints 6. I have 7 groups, but only 6 indices! 7th group doesn't even exist!

Как мне избежать такого поведения?Почему это происходит?Это ошибка?

1 Ответ

0 голосов
/ 08 февраля 2019

Проблема была вызвана опцией base.В зависимости от значения base, groupby не может создать правильное количество групп.

Поскольку в последней группе нет членов, filter ничего не удаляет, а вторая группа просто повторяет точно то, чтопервый сделал.

Проблема возникает только в Python 3 с версией панды <0.24. </p>

Это можно воспроизвести, выполнив

"Generate test dataframe"
case = 1
if case == 1:
    start = '2018-11-26 16:17:43.510000'
else:
    start = '2018-11-26 16:17:43.500000'

rng = pd.date_range(start, periods=10, freq='1S')
df = pd.DataFrame({'a':np.random.randn(len(rng)),'b':np.random.randn(len(rng))}, index=rng)

"Set interval and start time of the buckets"
interval = dt.timedelta(minutes=10)
t0 = df.index[0]
base = t0.minute + (t0.second +t0.microsecond/1e6)/60
groups = df.groupby(pd.Grouper(freq=interval, base=base))

print(groups.size())

Это генерирует 2 группы (одна изпустой) в случае 1, но только 1 в случае 2.

Это было решено в пандах 0.24 и обсуждается здесь: https://github.com/pandas-dev/pandas/issues/25161

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