【问题标题】:Re-categorize a column in a pandas dataframe重新分类熊猫数据框中的列
【发布时间】:2019-08-30 10:20:23
【问题描述】:

我正在尝试为存储在 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 中具有这些稀有材料标签的任何观察结果。这个answer 提供了一个有用的 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 类型的工作方式有关。如果是这样,有人可以解释如何重新分类列吗?或者如果这不可能,如何去除过滤后的虚拟对象中不必要的列?

谢谢!

【问题讨论】:

  • 你能查一下this吗?
  • 完美。试图完成相反的操作,但重新索引是关键。谢谢!

标签: python pandas dataframe categories dummy-variable


【解决方案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

删除未使用的_categories

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 的回答也有效,但更多地解决了消除虚拟矩阵列的下游问题。
【解决方案2】:

根据this answer,这可以通过重新索引和转置虚拟数据帧来解决:

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)
猜你喜欢
  • 2022-06-13
  • 2016-11-16
  • 1970-01-01
  • 2021-12-28
  • 2017-08-10
  • 2019-07-09
  • 1970-01-01
  • 2022-01-12
  • 1970-01-01
相关资源
最近更新 更多