我有一个在Python中使用的外壳数据帧。其中一根柱子上有"房子";等级";数据,这是基于一个实际的官方县分级系统。这些房屋按3-12的等级进行分级,描述如下:;良好"平均值"优秀";,等等。但是,列中的数据是字符串格式的,数字等级先出现,然后是空格,后面是描述。
因此例如一个条目可以读作">7平均";。(此处为更好的可视化(
我想先从字符串中消除数字,我可以这样做。然后我想把每个字符串条目转换成一个类别类型,我也可以这么做。但是,当我使用.cat.code
自动生成类别代码时,有没有办法使用原始的县规模(3-12(作为我的代码?我想我可以使用热编码,但我觉得这看起来很乱,很不专业。
编辑:我只是去掉了描述,保留了数字并转换为int,这很有效。然而,我仍然想看看我最初的问题是否有答案。
无法定义Categorical
数据类型的代码。当你试图设置代码时,这可能会引发两种异常:
>>> pd.Categorical.from_codes(...)
ValueError: codes need to be between -1 and len(categories)-1
>>> mycat.codes = [...]
AttributeError: can't set attribute
Categorical
数据类型使用-1表示缺失值,使用0表示N索引类别(通常按字典顺序表示字符串值(。
你能做的最好的事情就是创建这样的类别:
data = df['grade'].str.split(' ', 1, expand=True).astype({0: int})
grade = pd.CategoricalDtype(data.drop_duplicates(0).sort_values(0)[1], ordered=True, name='Grade')
df['grade'] = data[1].astype(grade)
输出:
>>> grade
CategoricalDtype(categories=['Low Average', 'Average', 'Good', 'Excellent'], ordered=True)
>>> df['grade']
0 Low Average
1 Average
2 Good
3 Excellent
Name: grade, dtype: category
Categories (4, object): ['Low Average' < 'Average' < 'Good' < 'Excellent']
>>> df['grade'].cat.codes
0 0
1 1
2 2
3 3
dtype: int8
由于您的数据已经具有内在的有序性,我们可以使其有序分类,然后重命名类别:
df.grade = pd.Categorical(df.grade, ordered=True)
df.grade = df.grade.cat.rename_categories(df.grade.cat.categories.str[2:])
给定:
df = pd.DataFrame({'grade':['6 Low Average', '5 Bad', '8 Good', '7 Average', '7 Average']})
print(df.sort_values('grade'))
# Output:
grade
1 5 Bad
0 6 Low Average
3 7 Average
4 7 Average
2 8 Good
操作:
df.grade = pd.Categorical(df.grade, ordered=True)
df.grade = df.grade.cat.rename_categories(df.grade.cat.categories.str[2:])
print(df.sort_values('grade'))
df.sort_values('grade').grade.cat.codes
# Output:
grade
1 Bad
0 Low Average
3 Average
4 Average
2 Good
1 0
0 1
3 2
4 2
2 3
dtype: int8
# If they weren't categorical ordered it'd look like:
# grade
# 3 Average
# 4 Average
# 1 Bad
# 2 Good
# 0 Low Average
可以这样做:
df = pd.DataFrame({'nr_grade': ['7 Average', '8 Good', '8 Good']})
df[['nr', 'grade']] = df['nr_grade'].str.split(' ', expand=True)
df['grade'] = pd.Categorical(df.grade, categories=df.grade.unique())
df.info()
输出:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 nr_grade 3 non-null object
1 nr 3 non-null object
2 grade 3 non-null category
dtypes: category(1), object(2)
memory usage: 303.0+ bytes