Как проверить, отличаются ли две категории категориальных панд только ярлыками категорий - PullRequest
0 голосов
/ 29 октября 2018

Предположим, у меня есть два категориальных pandas.Series, например:

> series_1 = pandas.Categorical(
    ["A", "B", "C", "A", "C"],
    categories=["A", "B", "C"]
)

> series_2 = pandas.Categorical(
    [1, 2, 3, 1, 3],
    categories=[1, 3, 2]
)

Итак, две серии имеют одинаковое информационное содержание, но отличаются только тем, как категории были помечены. Моя цель - проверить это очень быстро, потому что у меня есть фрейм данных с сотнями таких столбцов.

До сих пор я вычислял таблицу сопряженности с pandas.crosstab и проверял, является ли она диагональной матрицей (с np.diag(cont_table).sum() == cont_table.sum(), что не идеально).

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

Отсюда возникает вопрос: существует ли быстрый и простой способ выполнить эту проверку с помощью нескольких вызовов методов панд?


EDIT:

Изменен другой пример, который более четко демонстрирует сложность задачи, поскольку некоторые ответы работали для предыдущего примера, но не решают общую проблему. Обратите внимание, что я не могу поверить, что категории в двух сериях будут правильно соединены в том же порядке, что и соответствующие метки.

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

  1. генерирует два массива с одинаковой структурой, но разными метками
  2. метки создают две серии и вызывают метод .astype('category').

Обычно генерирует случаи, когда категории не в порядке.

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

Ну, после того, как я некоторое время ударился головой о документацию, оказалось, что я могу сделать это:

import pandas as pd

def compare_categorical_series():
    values_1, *_ = pd.factorize(feature_1)
    values_2, *_ = pd.factorize(feature_2)
    return np.all(values_1 == values_2)

Функция factorize преобразует каждую запись в целочисленное значение, используя одинаковое целое число для равенства. Конечно, этого недостаточно, это также необходимо делать всегда в одном и том же порядке, независимо от фактических меток.

Хотя это поведение не задокументировано в документации панд как есть, после всестороннего тестирования кажется, что это поведение. Кажется, что целые числа приписываются в том порядке, в котором метки появляются в серии, и этого будет достаточно, чтобы гарантировать поведение, необходимое для этого приложения.

Но так как это поведение не задокументировано, оно может измениться в будущем, поэтому хорошо иметь тестовые наборы для обнаружения возможных изменений в поведении.

0 голосов
/ 29 октября 2018

Если вы уверены, что порядок категорий такой же (как в этом примере), вы можете просто сделать:

series_match = (series_1 == series_2).all()
// True for this example
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...