Я пытаюсь построить простую модель классификации для своих данных, хранящихся в фрейме данных 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
. Если да, может ли кто-нибудь объяснить, как переклассифицировать столбец? Или, если это невозможно, как избавиться от ненужных столбцов в отфильтрованных макетах?
Спасибо!
Идеально. Пытаюсь добиться обратного, но ключом является переиндексация. Спасибо!
Для этот ответ это можно решить путем переиндексации и переноса фиктивного фрейма данных:
labels = filtered['material'].unique()
dummies = pd.get_dummies(filtered['material'])
dummies = dummies.T.reindex(labels).T
print(dummies.shape)
----------------------
(19963, 45)
лучше dummies = dummies.reindex(labels,axis=1)
Вы можете использовать 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]
Выбрано, потому что оно конкретно касается вопросов «перекатегоризации». Ответ @jezrael также работает, но в большей степени решает проблему устранения столбцов фиктивной матрицы.
Вы можете проверить это?