#python #pandas
Вопрос:
Я использую pd.get_dummies в приведенном ниже примере фрейма данных — и он работает правильно, но я хочу посмотреть, есть ли у кого-нибудь идея о том, как изменить результаты. Я опишу ниже:
Оригинальный DF
ID type AA23 A AB24 B DJ44 B KD33 C KD33 A BK89 B BL92 B BL92 C IO89 A
df после применения: pd.get_dummies(df, столбцы = [‘тип’],префикс = ‘тип’)
ID type_A type_B type_C AA23 1 0 0 AB24 0 1 0 DJ44 0 1 0 KD33 0 0 1 KD33 1 0 0 BK89 0 1 0 BL92 0 1 0 BL92 0 0 1 IO89 0 0 0
То, что я ищу, похоже, но для случаев, когда есть 2 или более идентификаторов (например, KD33 или BL92), мне нужна только одна строка на идентификатор и соответствующие столбцы типа, отмеченные 1. Например, с идентификатором = KD33 мне нужна одна строка, где «type_A» и «type_C» имеют 1.
ID type_A type_B type_C AA23 1 0 0 AB24 0 1 0 DJ44 0 1 0 KD33 1 0 1 BK89 0 1 0 BL92 0 1 1 IO89 0 0 0
Комментарии:
1.
pd.crosstab(df['ID'], df['type'])
Ответ №1:
Один из вариантов-просто сделать все это с помощью .groupby()
:
In [36]: df.groupby(["ID", "type"]).agg(lambda x: 1).unstack().fillna(0).astype(int).add_prefix("type_") Out[36]: type type_A type_B type_C ID AA23 1 0 0 AB24 0 1 0 BK89 0 1 0 BL92 0 1 1 DJ44 0 1 0 IO89 1 0 0 KD33 1 0 1
Вы также можете просто прикрепить .groupby
его к концу get_dummies
версии:
In [37]: pd.get_dummies(df, columns = ['type'],prefix = 'type').groupby("ID").sum() Out[37]: type_A type_B type_C ID AA23 1 0 0 AB24 0 1 0 BK89 0 1 0 BL92 0 1 1 DJ44 0 1 0 IO89 1 0 0 KD33 1 0 1
В этом небольшом примере первая версия немного быстрее, но требует большего количества массирования, чтобы получить тот же формат:
In [48]: %timeit df.groupby(["ID", "type"]).agg(lambda x: 1).unstack().fillna(0).astype(int).add_prefix("type_") 1.3 ms ± 8.61 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) In [49]: %timeit pd.get_dummies(df, columns = ['type'],prefix = 'type').groupby("ID").sum() 1.66 ms ± 1.48 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Комментарии:
1. Спасибо! FWIW второй вариант лучше всего работал с моим фактическим набором данных, который включал другие типы столбцов.
Ответ №2:
Вы можете использовать groupby.size
с unstack
:
print (df.groupby(["ID", "type"]).size().unstack(fill_value=0)) type A B C ID AA23 1 0 0 AB24 0 1 0 BK89 0 1 0 BL92 0 1 1 DJ44 0 1 0 IO89 1 0 0 KD33 1 0 1
Комментарии:
1. Не знал об
.size()
этом и всегда забывалfill_value
. 1