pandas.groupby по-разному реагирует на одни и те же данные, используя лямбда-аггфунк с категориальным типом и объектом - PullRequest
1 голос
/ 24 октября 2019

Я столкнулся с некоторым странным поведением pandas.groupby. В зависимости от типа столбцов данных я получаю два совершенно разных результата. Один из них, как и ожидалось, второй кажется странным.

Набор данных:

country id      plan   consolidation_key
AT01    1000    100    A
AT01    1000    200    B
AT01    2000    300    J
AT01    2000    200    K

в файле Excel.

import numpy as np

def consolidate(d):
    columns=['country', 'id', 'consolidation_key']
#    columns=['id', 'consolidation_key']
    return d.groupby(by=columns).agg(
        plans=pd.NamedAgg(
            column="plan", aggfunc=lambda s: "-".join(sorted(set(s.astype(str))))
        )
    )

d = pd.read_excel(r"path\to\file\test_data.xlsx", sheet_name='data')

data = d
df = consolidate(data)
print(df)
print("-----------")
print("dtypes:")
print(data.dtypes)
print("--------------------")

data2 = d.assign(country=lambda x: pd.Categorical(x["country"]))
df2 = consolidate(data2)
print(df2)
print("-----------")
print("dtypes:")
print(data2.dtypes)

Лямбда-функция в консолидации не полностью используется в данных примера. Он создает список уникальных предметов (100-200).

Результат, который он дает:

                               plans
country id   consolidation_key      
AT01    1000 A                   100
             B                   200
        2000 J                   300
             K                   200
-----------
dtypes:
country              object
id                    int64
plan                  int64
consolidation_key    object
dtype: object
--------------------
                               plans
country id   consolidation_key      
AT01    1000 A                   100
             B                   200
             J                   NaN
             K                   NaN
        2000 A                   NaN
             B                   NaN
             J                   300
             K                   200
-----------
dtypes:
country              category
id                      int64
plan                    int64
consolidation_key      object
dtype: object

Первое объединение в df выглядит хорошо. Второй в df2 имеет дополнительные элементы со значениями NaN. Это выглядит как перекрестное соединение для обоих идентификаторов. Интересно, что это происходит только тогда, когда columns=['country', 'id', 'consolidation_key']. С columns=['id', 'consolidation_key'] консолидация работает правильно в обоих случаях.

Вот большой вопрос - это ошибка в пандах или я что-то пропустил?

Версии:

  • Python 3.7.3
  • IPython 7.8.0
  • Панды 0.25.1 (и 0.25.2)

1 Ответ

0 голосов
/ 24 октября 2019

Читая посты в ответе @ jezrael, я пришел к важному комментарию на https://github.com/pandas-dev/pandas/issues/17594#issuecomment-545238294.

Добавление observed=True к groupby решает мою проблему.

def consolidate(d):
columns=['country', 'id', 'consolidation_key']
return d.groupby(by=columns, observed=True).agg(
    plans=pd.NamedAgg(
        column="plan", aggfunc=lambda s: "-".join(sorted(set(s.astype(str))))
    )
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...