重新分类 pandas 数据框中的列
Re-categorize a column in a pandas dataframe
我正在尝试为存储在 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
中具有这些罕见 material 标签的任何观察结果。 提供了一个有用的 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
这很好用,因为它确实过滤了带有稀有 material 标签的观察结果。但是,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)
您可以使用 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
删除unused_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]
我正在尝试为存储在 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
中具有这些罕见 material 标签的任何观察结果。
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
这很好用,因为它确实过滤了带有稀有 material 标签的观察结果。但是,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)
您可以使用 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
删除unused_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]