如何编码具有多种数据类型的数据集?
Posted
技术标签:
【中文标题】如何编码具有多种数据类型的数据集?【英文标题】:How to encode a dataset having multiple datatypes? 【发布时间】:2021-01-17 20:32:47 【问题描述】:我有一个像这样的数据集:
e = pd.DataFrame(
'col1': ['A', 'A', 'B', 'W', 'F', 'C'],
'col2': [2, 1, 9, 8, 7, 4],
'col3': [0, 1, 9, 4, 2, 3],
'col4': ['a', 'B', 'c', 'D', 'e', 'F']
)
在这里,我使用sklearn.preprocessing.LabelEncoder
对数据进行了编码。通过以下代码行:
x = list(e.columns)
# Import label encoder
from sklearn import preprocessing
# label_encoder object knows how to understand word labels.
label_encoder = preprocessing.LabelEncoder()
for i in x:
# Encode labels in column 'species'.
e[i] = label_encoder.fit_transform(e[i])
print(e)
但这甚至是对int
类型的数字数据点进行编码,这不是必需的。
编码数据集:
col1 col2 col3 col4
0 0 1 0 3
1 0 0 1 0
2 1 5 5 4
3 4 4 4 1
4 3 3 2 5
5 2 2 3 2
我该如何解决这个问题?
【问题讨论】:
【参考方案1】:一个非常简单的可能性是只用字符串值对列进行编码。例如,将您的代码调整为:
import pandas as pd
from sklearn import preprocessing
e = pd.DataFrame(
'col1': ['A', 'A', 'B', 'W', 'F', 'C'],
'col2': [2, 1, 9, 8, 7, 4],
'col3': [0, 1, 9, 4, 2, 3],
'col4': ['a', 'B', 'c', 'D', 'e', 'F']
)
label_encoder = preprocessing.LabelEncoder()
for col in e.columns:
if e[col].dtype == 'O':
e[col] = label_encoder.fit_transform(e[col])
print(e)
或者更好:
import pandas as pd
from sklearn import preprocessing
def encode_labels(ser):
if ser.dtype == 'O':
return label_encoder.fit_transform(ser)
else:
return ser
label_encoder = preprocessing.LabelEncoder()
e = pd.DataFrame(
'col1': ['A', 'A', 'B', 'W', 'F', 'C'],
'col2': [2, 1, 9, 8, 7, 4],
'col3': [0, 1, 9, 4, 2, 3],
'col4': ['a', 'B', 'c', 'D', 'e', 'F']
)
e_encoded = e.apply(encode_labels)
print(e_encoded)
【讨论】:
【参考方案2】:过滤并使您的预处理适应列类型是正确的想法,最有效的方法是使用 pandas 管道。
from sklearn.compose import ColumnTransformer
from sklearn.compose import make_column_selector
from sklearn.preprocecssing import LabelEncoder, StandardScaler
示例 1:根据列名应用转换器
my_transformer1 = ColumnTransformer(
[
('transform_name_for_col1', LabelEncoder(), 'col1'),
('transformer_name_for_col2_and_col3', StandardScaler(), ['col2', 'col3'])
]
)
示例 2:根据列类型应用转换器
my_transformer2 = ColumnTransformer(
[
('transform_name_categories', LabelEncoder(), make_column_selector(dtype_include=object)),
('transformer_name_for_numerical', StandardScaler(), make_column_selector(dtype_include=np.number))
]
)
显然,将 LabelEncoder 和 StandardScaler 替换为您选择的转换器,包括自定义转换器:
class MyCustomTransformer(BaseEstimator, TransformerMixin):
def __init__(self):
# do something
def fit(self, X, y = None):
# do something
return self
def transform(self, X, y = None):
# do something
# return something transformed
为了更进一步,我建议使用 scikit-learn Pipeline 根据列和/或列类型组合不同的预处理(这将更加灵活)。
在此处查看课程详情:
https://scikit-learn.org/stable/modules/generated/sklearn.compose.make_column_selector.html https://scikit-learn.org/stable/modules/generated/sklearn.compose.ColumnTransformer.html https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.Pipeline.html【讨论】:
非常感谢您提供如此详尽的回答!我会研究这个。以上是关于如何编码具有多种数据类型的数据集?的主要内容,如果未能解决你的问题,请参考以下文章