使用pd.Categorical.from_codes处理缺失值

3

假设我有:

df = pd.DataFrame({'gender': np.random.choice([1, 2], 10), 'height': np.random.randint(150, 210, 10)})

我希望将性别列转换为分类变量。如果我尝试使用以下代码:

df['gender'] = pd.Categorical.from_codes(df['gender'], ['female', 'male'])

它将失败。

我可以填充类别。

df['gender'] = pd.Categorical.from_codes(df['gender'], ['N/A', 'female', 'male'])

但是在一些方法中会返回'N/A'

In [67]: df['gender'].value_counts()
Out[67]: 
female    5
male      5
N/A       0
Name: gender, dtype: int64

我考虑使用None作为填充值。在value_counts中它可以正常工作,但是我收到了一个警告:

opt/anaconda3/bin/ipython:1: FutureWarning: 
Setting NaNs in `categories` is deprecated and will be removed in a future version of pandas.
  #!/opt/anaconda3/bin/python

有更好的方法吗?是否有一种明确从代码到类别的映射方式?

好的,我了解了df['gender'].cat.remove_unused_categories(inplace=True)。还在寻找更好的方法。 - Miki Tebeka
3个回答

1
你可以使用 rename_categories() 方法:
演示:
In [33]: df
Out[33]:
   gender  height
0       1     203
1       2     169
2       2     181
3       1     172
4       2     174
5       1     166
6       2     187
7       2     200
8       1     208
9       1     201

In [34]: df['gender'] = df['gender'].astype('category').cat.rename_categories(['male','feemale'])

In [35]: df
Out[35]:
    gender  height
0     male     203
1  feemale     169
2  feemale     181
3     male     172
4  feemale     174
5     male     166
6  feemale     187
7  feemale     200
8     male     208
9     male     201

In [36]: df.dtypes
Out[36]:
gender    category
height       int32
dtype: object

1
将新的类别直接分配给它的 .categories 属性,然后它将被重命名为这些值:
df['gender'] = df['gender'].astype('category')
df['gender'].cat.categories = ['female', 'male']

df['gender'].value_counts()
Out[23]:
female    7
male      3
Name: gender, dtype: int64

df.dtypes
Out[24]:
gender    category
height       int32
dtype: object

如果您想要一个代码和其对应类别的映射字典,那么:
old = df['gender'].cat.categories
new = ['female', 'male']

dict(zip(old, new))
Out[28]:
{1: 'female', 2: 'male'}

1
谢谢。我看到的问题(也包括我的解决方案)是df['gender'].cat.codes不是原始数据中的[1,2]而是[0,1]。我会标记为已解决,因为我认为不会有更好的解决方案了。 - Miki Tebeka

0

你从 pd.Categorical.from_codes(df['gender'], ['female', 'male']) 得到的错误应该提醒你,你的 codes 需要以0为索引。

因此,您可以通过您的 DataFrame 声明来实现它。

df = pd.DataFrame({'gender': np.random.choice([0, 1], 10), 'height': np.random.randint(150, 210, 10)})

谢谢,但是在我的情况下,数据来自外部来源,我对“gender”值没有控制。 - Miki Tebeka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接