Сохранение исходных категориальных сопоставлений при объединении нескольких фреймов данных - PullRequest
0 голосов
/ 26 ноября 2018

У меня есть n фреймы данных с одним столбцом каждый, который имеет dtype category.Столбцы разных фреймов частично перекрываются.Я хочу поделиться категорией -> ID сопоставления между столбцами при объединении их в новый фрейм:

In [362]: af = pd.DataFrame(pd.Series(['a1','a2', 'b1'], dtype="category", name='a'))

In [365]: bf = pd.DataFrame(pd.Series(['b1','b2', 'a1'], dtype="category", name='b'))

In [373]: all_categories = pd.Categorical(['a1','a2','b1','b2'])

In [376]: show_mapping(af.a)
[('a1', 0), ('a2', 1), ('b1', 2)]

In [377]: af.a.cat =  all_categories

In [378]: show_mapping(af.a)
[('a1', 0), ('a2', 1), ('b1', 2), ('b2', 3)]

In [379]: show_mapping(bf.b)
[('b2', 0), ('a1', 1), ('b1', 2)]

In [380]: bf.b.cat =  all_categories

In [381]: show_mapping(bf.b)
[('a1', 0), ('a2', 1), ('b1', 2), ('b2', 3)]

Теперь я объединяю эти фреймы с тем, что, как я предполагал, теперь является идентичным отображением:

In [382]: df = af.join(bf)

Но когда я печатаю сопоставление столбцов, они сбрасываются:

In [384]: show_mapping(df.a)
[('a1', 0), ('a2', 1), ('b1', 2)]

In [385]: show_mapping(df.b)
[('b2', 0), ('a1', 1), ('b1', 2)]

Почему сопоставления автоматически переделываются при объединении кадров и как я могу достичь того, что планировал?


def show_mapping(x):
    print(list(sorted(zip(x.cat.categories, x.cat.codes), key=lambda x : x[1])))

edit

вся путаница возникла из-за использования плохой функции показа.Следующая функция шоу на самом деле работает правильно.В сочетании с методом set_categories вместо .cat = ... все получается правильно:

def show_mapping(s):
    print([(e, s.cat.codes[i]) for i, e in enumerate(s)])

1 Ответ

0 голосов
/ 26 ноября 2018

Вы можете использовать set_categories на all_categories для использования одинаковых категорий в каждом категориальном столбце, поэтому после join получите одинаковые коды:

af = pd.DataFrame(pd.Series(['a1','a2', 'b1'], dtype="category", name='a'))
bf = pd.DataFrame(pd.Series(['b1','b2', 'a1'], dtype="category", name='b'))

def show_mapping(x): 
    return (list(sorted(zip(x.cat.categories, x.cat.codes), key=lambda x : x[1]))) 

print(af.a)
0    a1
1    a2
2    b1
Name: a, dtype: category
Categories (3, object): [a1, a2, b1]

all_categories = pd.Categorical(['a1','a2','b1','b2'])

af.a = af.a.cat.set_categories(all_categories)
bf.b = bf.b.cat.set_categories(all_categories)

Добавлена ​​категория b2:

print(af.a)
0    a1
1    a2
2    b1
Name: a, dtype: category
Categories (4, object): [a1, a2, b1, b2]

print(show_mapping(af.a))
[('a1', 0), ('a2', 1), ('b1', 2)]

print(show_mapping(bf.b))
[('b1', 0), ('a1', 2), ('a2', 3)]

df = af.join(bf)

print(show_mapping(df.a))
[('a1', 0), ('a2', 1), ('b1', 2)]

print(show_mapping(df.b))
[('b1', 0), ('a1', 2), ('a2', 3)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...