第一个问题是:您希望单独对每一列进行编码还是使用一种编码对所有列进行编码?
表达方式df = df.astype(str).apply(LabelEncoder().fit_transform)
意味着您单独对所有列进行编码。
That case you can do the following:
df = df.apply(lambda series: pd.Series(
LabelEncoder().fit_transform(series[series.notnull()]),
index=series[series.notnull()].index
))
print(df)
Out:
A B C
0 0.0 0 1.0
1 NaN 1 0.0
2 1.0 2 NaN
下面解释它是如何工作的。但是,首先,我将介绍该解决方案的一些缺点。
缺点
首先,存在混合类型的列:如果列包含NaN
值,那么列有一个类型float
,因为 nan 是 python 中的浮点数。
df.dtypes
A float64
B int64
C float64
dtype: object
对于标签来说似乎毫无意义。好的,稍后您可以忽略所有 nan,并将其余部分转换为整数。
第二点是:可能你需要记住一个LabelEncoder
- 因为通常需要进行逆变换等操作。但是这个解决方案不记住编码器,你没有这样的变量。
一个简单、明确的解决方案是:
encoders = dict()
for col_name in df.columns:
series = df[col_name]
label_encoder = LabelEncoder()
df[col_name] = pd.Series(
label_encoder.fit_transform(series[series.notnull()]),
index=series[series.notnull()].index
)
encoders[col_name] = label_encoder
print(df)
Out:
A B C
0 0.0 0 1.0
1 NaN 1 0.0
2 1.0 2 NaN
- 更多代码,但结果是相同的
print(encoders)
Out
{'A': LabelEncoder(), 'B': LabelEncoder(), 'C': LabelEncoder()}
- 此外,还可以使用编码器。逆变换(也应该删除之前的 nan!):
encoders['B'].inverse_transform(df['B'])
Out:
array([1, 6, 9])
此外,一些选项(例如编码器的某些注册表超类)也可用,它们与第一个解决方案兼容,但更容易迭代列。
怎么运行的
The df.apply(lambda series: ...)
应用一个返回的函数pd.Series
到每一列;因此,它返回一个包含新值的数据帧。
逐步表达:
pd.Series(
LabelEncoder().fit_transform(series[series.notnull()]),
index=series[series.notnull()].index
)
- series[series.notnull()]
drop NaN
值,然后将其余的输入到fit_transform
.
- 当标签编码器返回一个numpy.array
并抛出一个索引,index=series[series.notnull()].index
恢复它以正确连接它。如果不做索引:
print(df)
Out:
A B C
0 x 1 2.0
1 NaN 6 1.0
2 z 9 NaN
df = df.apply(lambda series: pd.Series(
LabelEncoder().fit_transform(series[series.notnull()]),
))
print(df)
Out:
A B C
0 0.0 0 1.0
1 1.0 1 0.0
2 NaN 2 NaN
- 价值观从正确的位置转移 - 甚至IndexError
可能发生。
所有列均采用单一编码器
在这种情况下,堆栈数据帧,适合编码器,然后取消堆栈
series_stack = df.stack().astype(str)
label_encoder = LabelEncoder()
df = pd.Series(
label_encoder.fit_transform(series_stack),
index=series_stack.index
).unstack()
print(df)
Out:
A B C
0 5.0 0.0 2.0
1 NaN 3.0 1.0
2 6.0 4.0 NaN
- 作为series_stack
is pd.Series
含有NaN
的,DataFrame 中的所有值都是浮点数,因此您可能更愿意对其进行转换。
希望能帮助到你。