Переклассифицировать столбец в кадре данных панд - PullRequest
2 голосов
/ 09 апреля 2019

Я пытаюсь построить простую классификационную модель для моих данных, хранящихся в кадре данных pandas train.Чтобы сделать эту модель более эффективной, я создал список имен столбцов известных мне столбцов для хранения категориальных данных, который называется category_cols.Я классифицирую эти столбцы следующим образом:

# Define the lambda function: categorize_label
categorize_label = lambda x: x.astype('category')

# Convert train[category_cols] to a categorical type
train[category_cols] = train[category_cols].apply(categorize_label, axis=0)

Моя целевая переменная material является категориальной и имеет 64 уникальных метки, которым она может быть назначена.Тем не менее, некоторые из этих меток появляются только один раз в train, что слишком мало, чтобы хорошо обучить модель.Поэтому я бы хотел отфильтровать любые наблюдения в train, которые имеют эти метки редких материалов.Этот ответ предоставил полезную комбинацию groupby + filter:

print('Num rows: {}'.format(train.shape[0]))
print('Material labels: {}'.format(len(train['material'].unique())))

min_count = 5
filtered = train.groupby('material').filter(lambda x: len(x) > min_count)
print('Num rows: {}'.format(filtered.shape[0]))
print('Material labels: {}'.format(len(filtered['material'].unique())))
----------------------
Num rows: 19999
Material labels: 64
Num rows: 19963
Material labels: 45

Это прекрасно работает, поскольку оно фильтрует наблюдения по меткам редких материалов.Однако что-то скрытое в типе category, похоже, поддерживает все предыдущие значения для material даже после того, как они были отфильтрованы.Это становится проблемой при попытке создать фиктивные переменные, и происходит, даже если я пытаюсь повторно запустить тот же метод категоризации:

filtered[category_cols] = filtered[category_cols].apply(categorize_label, axis=0)
print(pd.get_dummies(train['material']).shape)
print(pd.get_dummies(filtered['material']).shape)
----------------------
(19999, 64)
(19963, 64)

Я ожидал бы, что форма отфильтрованных манекенов будет (19963, 45),Однако pd.get_dummies включает столбцы для меток, которые не отображаются в filtered.Я предполагаю, что это как-то связано с тем, как работает тип category.Если да, то может ли кто-нибудь объяснить, как повторно классифицировать столбец?Или, если это невозможно, как избавиться от ненужных столбцов в отфильтрованных макетах?

Спасибо!

Ответы [ 2 ]

1 голос
/ 09 апреля 2019

За этот ответ , это можно решить путем переиндексации и транспонирования фиктивного фрейма данных:

labels = filtered['material'].unique()

dummies = pd.get_dummies(filtered['material'])
dummies = dummies.T.reindex(labels).T
print(dummies.shape)
----------------------
(19963, 45)
0 голосов
/ 09 апреля 2019

Вы можете использовать category.cat.remove_unused_categories:

Использование

df['category'].cat.remove_unused_categories(inplace=True)

Пример

df = pd.DataFrame({'label': list('aabbccd'),
                   'value': [1] * 7})
print(df)

  label  value
0     a      1
1     a      1
2     b      1
3     b      1
4     c      1
5     c      1
6     d      1

Позволяет установить label в качестве категории типа

df['label'] = df.label.astype('category')
print(df.label)

0    a
1    a
2    b
3    b
4    c
5    c
6    d
Name: label, dtype: category
Categories (4, object): [a, b, c, d]

Фильтр DataFrame для удаления label d

df = df[df.label.ne('d')]
print(df)

  label  value
0     a      1
1     a      1
2     b      1
3     b      1
4     c      1
5     c      1

Удалить неиспользованные_категории

df.label.cat.remove_unused_categories(inplace=True)
print(df.label)

0    a
1    a
2    b
3    b
4    c
5    c
Name: label, dtype: category
Categories (3, object): [a, b, c]
...