Пересмотрите другое поведение с помощью agg и вызова функции - PullRequest
0 голосов
/ 14 декабря 2018

У меня есть pandas.DataFrame с именем data с такой структурой:

                       id         action
date                                    
1900-11-01 00:00:00  10.0    starts_game
1900-11-01 00:05:00  10.0  team_a_scores
1900-11-01 00:25:00  10.0  team_a_scores
1900-11-01 00:30:00  10.0  team_a_scores
1900-11-01 00:55:00  10.0  team_b_scores
1900-11-01 23:58:00  99.0    starts_game
1900-11-02 00:40:00  99.0  team_b_scores
1900-11-02 00:50:00  99.0  team_b_scores
1900-11-03 00:05:00  10.0    starts_game
1900-11-03 00:24:00  10.0  team_b_scores

Я хочу пересчитывать его каждую минуту и ​​использовать разные стратегии повышения частоты дискретизации.С помощью столбца id я буду заполнять его вперед, а с помощью action я буду заполнять только значения с повышенной дискретизацией с помощью 'Playing'.

Проблема в том, что результат будет другим, если я выполню ffill непосредственно для повторно сэмплированногоdatafrme и с функцией agg, давайте посмотрим на это:

data.resample('T').ffill().head()

                       id       action
date                                  
1900-11-01 00:00:00  10.0  starts_game
1900-11-01 00:01:00  10.0  starts_game
1900-11-01 00:02:00  10.0  starts_game
1900-11-01 00:03:00  10.0  starts_game
1900-11-01 00:04:00  10.0  starts_game

Но, напомни, я хотел, чтобы столбец action был только строкой 'Playing', поэтому:

data.resample('T').agg(dict(id='ffill', action=lambda _: 'playing')).head()



                       id   action
date                              
1900-11-01 00:00:00  10.0  playing
1900-11-01 00:01:00   NaN  playing
1900-11-01 00:02:00   NaN  playing
1900-11-01 00:03:00   NaN  playing
1900-11-01 00:04:00   NaN  playing

Я не понимаю, почему идентификатор не вычитается правильно, любая идея?

Для простоты воспроизведения это csv:

date,id,action
1900-11-01 00:00:00,10.0,starts_game
1900-11-01 00:05:00,10.0,team_a_scores
1900-11-01 00:25:00,10.0,team_a_scores
1900-11-01 00:30:00,10.0,team_a_scores
1900-11-01 00:55:00,10.0,team_b_scores
1900-11-01 23:58:00,99.0,starts_game
1900-11-02 00:40:00,99.0,team_b_scores
1900-11-02 00:50:00,99.0,team_b_scores
1900-11-03 00:05:00,10.0,starts_game
1900-11-03 00:24:00,10.0,team_b_scores

И код:

import pandas as pd


filename = 'your_custom_name.csv'
data = pd.read_csv(filename)

data = data.set_index('date')

1 Ответ

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

Причина, по которой agg не работает, состоит в том, что resample('T') возвращает groupby -подобную структуру с группами, представляющими собой поминутные строки *, применяется 1004 *

>>> data.resample('T').groups
{Timestamp('1900-11-01 00:00:00', freq='T'): 1,
 Timestamp('1900-11-01 00:01:00', freq='T'): 1,
 Timestamp('1900-11-01 00:02:00', freq='T'): 1,
 Timestamp('1900-11-01 00:03:00', freq='T'): 1,
 Timestamp('1900-11-01 00:04:00', freq='T'): 1, ...

aggнад группой, которая в данном случае представляет собой всего одну строку, означающую, что лямбда с радостью вернет скаляр и ffill выберет единственный доступный элемент.

Если бы вы пересчитали его, например, за день

>>> data.resample('D').groups
{Timestamp('1900-11-01 00:00:00', freq='D'): 6,
 Timestamp('1900-11-02 00:00:00', freq='D'): 8,
 Timestamp('1900-11-03 00:00:00', freq='D'): 10}

было бы наоборот.Ваша лямбда будет возвращать только одно значение для всех 6 элементов первой группы, но метод 'ffill' будет работать, как и ожидалось, распространяя первое встреченное не NaN значение вперед

>>> data.resample('D').agg({'id': 'ffill', 'action': lambda _: 'playing'})
                       id   action
date                              
1900-11-01 00:00:00  10.0  playing
1900-11-01 00:05:00  10.0      NaN
1900-11-01 00:25:00  10.0      NaN
1900-11-01 00:30:00  10.0      NaN
1900-11-01 00:55:00  10.0      NaN
1900-11-01 23:58:00  99.0      NaN
1900-11-02 00:00:00   NaN  playing
1900-11-02 00:40:00  99.0      NaN
1900-11-02 00:50:00  99.0      NaN
1900-11-03 00:00:00   NaN  playing
1900-11-03 00:05:00  10.0      NaN
1900-11-03 00:24:00  10.0      NaN

Яне уверен, что вся операция может быть выполнена за один раз, но следующее должно работать

df = data.resample('T').first()
df['id'] = df['id'].ffill()
df['action'] = df['action'].fillna('playing')

, давая вам

                       id         action
date                                    
1900-11-01 00:00:00  10.0    starts_game
1900-11-01 00:01:00  10.0        playing
1900-11-01 00:02:00  10.0        playing
1900-11-01 00:03:00  10.0        playing
1900-11-01 00:04:00  10.0        playing
1900-11-01 00:05:00  10.0  team_a_scores
1900-11-01 00:06:00  10.0        playing
1900-11-01 00:07:00  10.0        playing

ОБНОВЛЕНИЕ

Вместо resample вы можете использовать asfreq, который возвращает простой DataFrame и ведет себя так, как вы ожидаете, до

>>> data.asfreq('T').agg({'id': 'ffill', 'action': lambda _: 'playing'})
                       id   action
date                              
1900-11-01 00:00:00  10.0  playing
1900-11-01 00:01:00  10.0  playing
1900-11-01 00:02:00  10.0  playing
1900-11-01 00:03:00  10.0  playing
1900-11-01 00:04:00  10.0  playing

, что изменит вышеуказанное решение на

df = data.asfreq('T')
df['id'] = df['id'].ffill()
df['action'] = df['action'].fillna('playing')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...