【问题标题】: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

我该如何解决这个问题?

【问题讨论】:

    标签: python-3.x dataframe scikit-learn sklearn-pandas label-encoding


    【解决方案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 根据列和/或列类型组合不同的预处理(这将更加灵活)。

      在此处查看课程详情:

      【讨论】:

      • 非常感谢您提供如此详尽的回答!我会研究这个。
      猜你喜欢
      • 2022-11-28
      • 2020-02-07
      • 1970-01-01
      • 2015-10-26
      • 1970-01-01
      • 2015-08-06
      • 1970-01-01
      • 2021-12-27
      • 1970-01-01
      相关资源
      最近更新 更多