Сэмплирование данных с учетом значений NaN + панд - PullRequest
1 голос
/ 07 мая 2019

У меня есть фрейм данных, как показано ниже. Я хочу сделать выборку с «3S» Так что есть ситуации, когда присутствует NaN. Я ожидал, что фрейм данных должен выполнять выборку с помощью «3S», а также, если между ними обнаружен какой-либо «NaN», тогда остановиться на этом и начать выборку с этого индекса. Я попытался использовать метод dataframe.apply для достижения, но это выглядит очень сложно. Есть ли какой-нибудь короткий путь для достижения?

df.sample(n=3)

Код для генерации ввода:

index = pd.date_range('1/1/2000', periods=13, freq='T')
series = pd.DataFrame(range(13), index=index)
print series

series.iloc[4] = 'NaN'
series.iloc[10] = 'NaN'

Я пытался сделать выборку, но после этого понятия не имею, как поступить.

2015-01-01 00:00:00    0.0
2015-01-01 01:00:00    1.0
2015-01-01 02:00:00    2.0
2015-01-01 03:00:00    2.0
2015-01-01 04:00:00    NaN
2015-01-01 05:00:00    3.0
2015-01-01 06:00:00    4.0
2015-01-01 07:00:00    4.0
2015-01-01 08:00:00    4.0
2015-01-01 09:00:00    NaN
2015-01-01 10:00:00    3.0
2015-01-01 11:00:00    4.0
2015-01-01 12:00:00    4.0

Новый фрейм данных должен производить выборку на основе «3S», а также учитывать «NaN», если таковой имеется, и начинать выборку оттуда, где находятся записи «NaN».

Ожидаемый результат:

2015-01-01 02:00:00    2.0 -- Sampling after 3S
2015-01-01 03:00:00    2.0 -- Print because NaN has found in Next
2015-01-01 04:00:00    NaN -- print NaN record
2015-01-01 07:00:00    4.0 -- Sampling after 3S
2015-01-01 08:00:00    4.0 -- Print because NaN has found in Next
2015-01-01 09:00:00    NaN -- print NaN record
2015-01-01 12:00:00    4.0 -- Sampling after 3S

Ответы [ 2 ]

1 голос
/ 07 мая 2019

Использование:

index = pd.date_range('1/1/2000', periods=13, freq='H')
df = pd.DataFrame({'col': range(13)}, index=index)
df.iloc[4, 0] = np.nan
df.iloc[9, 0] = np.nan

print (df)
                      col
2000-01-01 00:00:00   0.0
2000-01-01 01:00:00   1.0
2000-01-01 02:00:00   2.0
2000-01-01 03:00:00   3.0
2000-01-01 04:00:00   NaN
2000-01-01 05:00:00   5.0
2000-01-01 06:00:00   6.0
2000-01-01 07:00:00   7.0
2000-01-01 08:00:00   8.0
2000-01-01 09:00:00   NaN
2000-01-01 10:00:00  10.0
2000-01-01 11:00:00  11.0
2000-01-01 12:00:00  12.0

m = df['col'].isna()
s1 = m.ne(m.shift()).cumsum()
t = pd.Timedelta(2, unit='H')
mask = df.index >= df.groupby(s1)['col'].transform(lambda x: x.index[0]) + t

df1 = df[mask | m]
print (df1)
                      col
2000-01-01 02:00:00   2.0
2000-01-01 03:00:00   3.0
2000-01-01 04:00:00   NaN
2000-01-01 07:00:00   7.0
2000-01-01 08:00:00   8.0
2000-01-01 09:00:00   NaN
2000-01-01 12:00:00  12.0

Объяснение :

  1. Создать маску для сравнения отсутствующих значений с помощью Series.isna
  2. Создание групп по последовательным значениям путем сравнения сдвинутых значений с Series.ne (! =)

print (s1)
2000-01-01 00:00:00    1
2000-01-01 01:00:00    1
2000-01-01 02:00:00    1
2000-01-01 03:00:00    1
2000-01-01 04:00:00    2
2000-01-01 05:00:00    3
2000-01-01 06:00:00    3
2000-01-01 07:00:00    3
2000-01-01 08:00:00    3
2000-01-01 09:00:00    4
2000-01-01 10:00:00    5
2000-01-01 11:00:00    5
2000-01-01 12:00:00    5
Freq: H, Name: col, dtype: int32
Получите первое значение индекса по группам, добавьте тимдельту (для ожидаемого результата добавлены 2T) и сравните по DatetimeIndex Последний фильтр по boolean indexing и связанные маски по | для bitwise OR
1 голос
/ 07 мая 2019

Один из способов - заполнить NA 0:

.
df['Col_of_Interest'] = df['Col_of_Interest'].fillna(0)

А затем выполните повторную выборку для серии: (если datetime ваш индекс)

series.resample('30S').asfreq()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...