Скользящий счет pandas для категориальных переменных с использованием времени - PullRequest
1 голос
/ 27 мая 2020

У меня есть фрейм данных, который выглядит следующим образом:

Datetime   | Category | ID
--------------------------
2020-01-30 | A        | 1
2020-02-01 | B        | 1
2020-02-02 | A        | 1
2020-02-20 | A        | 1
2020-01-28 | B        | 2
2020-01-29 | C        | 2
2020-01-30 | C        | 2
2020-01-31 | D        | 2
2020-02-01 | D        | 2
2020-02-02 | D        | 2
2020-02-03 | C        | 2

Я хотел бы получить две самые частые категории для каждого идентификатора в течение 1-недельного окна строки (за исключением текущей строки). Возможно ли это в pandas? Я пытался использовать .rolling и .value_counts, но, похоже, это не работает. Спасибо!

Ниже приведен фрейм данных, который я хотел бы получить:

Datetime   | Category | ID
--------------------------
2020-01-30 | NaN      | 1
2020-02-01 | [A, ""]  | 1
2020-02-02 | [A, B]   | 1
2020-02-20 | NaN      | 1
2020-01-28 | Nan      | 2
2020-01-29 | [B,""]   | 2
2020-01-30 | [B,C]    | 2
2020-01-31 | [B,C]    | 2
2020-02-01 | [C,D]    | 2
2020-02-02 | [C,D]    | 2
2020-02-03 | [C,D]    | 2

Спасибо!

Edit Ответ pd.get_dummies: отлично, но поскольку мой набор данных огромен, он неэффективен. Был бы очень признателен, если бы у кого-нибудь есть эффективное решение для этого! Спасибо!

1 Ответ

0 голосов
/ 27 мая 2020

Вы можете использовать resample() вместо rolling(), потому что частота вашего временного индекса - ежедневно, и вам нужна еженедельная статистика, поэтому попробуйте что-то вроде этого:

df.groupby('ID').resample('1w').apply(lambda s: s.value_counts().head(2))

Обратите внимание, что это работает только в версиях of Pandas, где apply() разделяет данные на pd.Series, а не np.arrays. Также, если у вас есть больше столбцов в вашем фрейме данных, может потребоваться указать имя столбца в лямбда-функциях, ie.:

df.groupby('ID').resample('1w').apply(lambda s: s['Category'].value_counts().head(2))

И если вам нужно исключить первую строку в окне, используйте iloc[] нарезка:

df.groupby('ID').resample('1w').apply(lambda s: s['Category'].iloc[1:].value_counts().head(2))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...