在Pandas DataFrame列中进行整数编码后保留数据类型为category

4

我有一个从csv读取的Pandas DataFrame,其中有一些列具有字符串值但实际上是object类型。因为它们是分类变量,所以我将它们转换为category类型,然后转换为整数表示形式,然后我正在拟合随机森林回归器。

for col in df_raw.select_dtypes(include='object'):
    df_raw[col] = df_raw[col].astype('category')
    df_raw[col] = df_raw[col].cat.codes #not 'category' type anymore.

问题在于,如果我这样做,那么 dtype 会立即转换为 int,我将失去后面需要的 cat 信息。
例如,在循环的第一行之后,我可以运行 df_raw[col].cat,并像预期的那样获得索引类别。但是一旦执行第二行,列的 dtype 就会更改为 int8,我将会得到错误提示:

只能在 'category' dtype 上使用 .cat 访问器

从某种意义上讲,这是有道理的,因为它的 dtypeint8是否可能在同一 DataFrame 中保留类别编码信息,并同时具有整数编码以适应回归器?如何实现?

请提供一个输入示例。 - roganjosh
一个更精确的 MCVE 确实有助于准确地找出问题并给出答案。 - sophros
你想让你的(现在正确)整数编码列成为分类dtype的原因是什么?列数据类型的主要原因是为了使pandas/numpy能够高效地处理它们... - G. Anderson
@roganjosh 我已经更新了问题,现在完整了吗? - DaveIdito
@G.Anderson,只是因为我希望能够稍后查找编码,而不必跟踪额外的列或新变量。或者说,为了便于重新排序。 - DaveIdito
这听起来像是一个X->Y问题。你可能想阅读一下关于反转sklearn labelencoder的答案,因为仅仅拥有一个数字列并不能解决你实际的问题。你可以在这个问题上查看答案。 - G. Anderson
2个回答

1

1. 简单的想法

为什么不在回归器拟合中使用派生列,例如:

df_raw[col + '_calculated'] = df_raw[col].cat.codes

以这种方式,您既有一个不改变此特征的分类列 col ,又有一个“计算”列,其中包含 int 以供进一步处理? 2. 更聪明的方法 另一种方法可能是在将数据框传递给 fit 方法之前对其进行封装,使回归器直接访问 .cat.codes 而不是直接访问分类值:
def access_wrapper(dframe, col):
   yield from dframe[col].cat.codes

fit(..., access_wrapper(df, col))

以这种方式,您不会对数据框造成影响,并且不会通过调用来复制的值,每次访问该值都应该相当快速。

如果我理解正确的话,那么我基本上是通过遵循上述步骤添加了一列额外的列。我有大约20个分类列,这意味着要向数据框中添加20个新列。这正是我想要避免的。 - DaveIdito
请看我建议的第二种方法。这里应该使用一种访问器形式来帮助您。而且它相当高效(特别是在内存方面)。 - sophros
我喜欢第二种方法,它回答了我的原始问题。 - DaveIdito

0

您可以使用

train.col = pd.Categorical(train.col)

将其从整数类型转回分类类型

然后运行

train.col.cat.codes  

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