#python #pandas #group-by #pandas-groupby
#питон #панды #группа-по #панды-групповые
Вопрос:
Исходный кадр данных является:
import pandas as pd array = {'id': [1, 1, 1, 1, 2, 3], 'color': ['yellow', 'red', 'yellow', 'red', 'yellow', 'white']} df = pd.DataFrame(array) df id color 1 yellow 1 red 1 yellow 1 red 2 yellow 3 white
Я преобразовал его в следующий фрейм данных с помощью get_dummies:
df = pd.get_dummies(df, prefix='', prefix_sep='') df id red white yellow 0 1 0 0 1 1 1 1 0 0 2 1 0 0 1 3 1 1 0 0 4 2 0 0 1 5 3 0 1 0
который я хочу сгруппировать по() столбцу «идентификатор»:
df.groupby(['id']).max() red white yellow id 1 1 0 1 2 0 0 1 3 0 1 0
Однако мой исходный кадр данных состоит из 8000 строк на 1 500 000 столбцов, что делает эту операцию слишком медленной.
Есть какие-нибудь идеи о том, как сделать это быстрее?
Комментарии:
1. Какова ваша модель данных, если ваш фрейм данных настолько широк?
2. Что вы подразумеваете под моделью данных?
3. Сколько у вас групп в 8000 строк?
4. Я обновил свой ответ
5. помогает ли это: :
df.groupby([*df]).size().clip(upper=1).unstack('color', fill_value=0)
Ответ №1:
Обновить
Основываясь на вашем исходном фрейме данных, я бы создал уникальный фрейм данных и свернул (или закодировал) его позже. Таким образом, вы полностью избегаете любого последующего агрегирования.
df_unique = df.drop_duplicates() df_unique["val"] = 1 df_unique id color val 0 1 yellow 1 1 1 red 1 4 2 yellow 1 5 3 white 1 df_unique.set_index("id").pivot(columns="color").fillna(0) red white yellow id 1 1.0 0.0 1.0 2 0.0 0.0 1.0 3 0.0 1.0 0.0
Варианты кодирования
Пожалуйста, попробуйте изменить форму ваших данных (что также отнимает много времени), но может быть быстрее, чем ваш текущий широкий формат:
# first approach using melt.groupby.max pd.melt(df, id_vars = 'id').groupby(["id", "variable"]).max() # second approach using melt.sort.groupby.first pd.melt(df, id_vars = 'id').sort_values(by="variable", ascending=True).groupby(["id", "variable"]).first()
Вы можете запустить это позже, чтобы снова сохранить желаемую форму:
melted_and_aggregated_df.reset_index(level=["variable"]).pivot(columns=["variable"], values="value")
Размер Данных
Помимо чистой эффективности кодирования, постарайтесь уменьшить объем ваших данных.
- В случае, если есть группы, в которых есть только одна строка, вы должны использовать подход max/first только для других групп, а затем объединить результаты.
- Существует ли на самом деле 1,5 миллиона цветов? Звучит грандиозно. Вам действительно нужны все они или их можно предварительно уменьшить/агрегировать?
Комментарии:
1. Спасибо!!! Вы уверены, что таяние происходит быстрее? Применение его к короткому кадру данных, который я опубликовал выше, занимает 3 мс, когда исходная функция groupby() занимает 1 мс
2. Цвета — это всего лишь пример. Данные реального мира закодированы по-другому
3. Нет, я не уверен. Это просто еще один способ решения этой проблемы. Основной акцент должен делаться на сокращении объема ваших данных до их агрегирования. Я сомневаюсь, что есть вариант, который был бы очень быстрым, учитывая большой размер данных
4. нет… плавление не должно быть быстрее, вы увеличиваете количество строк, что не обеспечивает никакой эффективности. Я бы предположил, что более быстрым решением, чем groupby, должно быть решение, которое уменьшает количество строк и позволяет выполнять векторизованные операции со столбцами
5. Можете ли вы вместо этого поделиться исходным кадром данных, поделиться своим конечным ожидаемым результатом