机器学习中级课程 3.分类变量

机器学习中级教程

有很多非数字数据。下面是如何将其用于机器学习。

在本教程中,您将了解什么是分类变量,以及处理此类数据的三种方法。

正文

介绍

分类变量只接受有限数量的值。

  • 考虑一项调查,询问你多久吃一次早餐,并提供四个选项:“从不”、“很少”、“大多数天”或“每天”。在这种情况下,数据是分类的,因为响应属于一组固定的类别。
  • 如果人们对他们所拥有的汽车品牌进行调查,他们的回答会分为“本田”、“丰田”和“福特”等类别。在这种情况下,数据也是分类的。

如果试图将这些变量插入Python中的大多数机器学习模型,而不首先对它们进行预处理,则会出现错误。在本教程中,我们将比较三种可用于准备分类数据的方法。

三种方法

1) 删除分类变量

处理分类变量最简单的方法就是从数据集中删除它们。只有在列中不包含有用信息的情况下,这种方法才能很好地工作。

2) 顺序编码

顺序编码将每个唯一值分配给不同的整数。
order
这种方法假设类别的顺序是:“从不”(0)<“很少”(1)<“大多数天”(2)<“每天”(3)。

在这个例子中,这个假设是有道理的,因为分类有一个无可争议的排名。并不是所有的分类变量在值中都有明确的顺序,但我们把那些有顺序的变量称为顺序变量。对于基于树的模型(如决策树和随机森林),可以预期顺序编码可以很好地处理顺序变量。

3) One-Hot 编码

one-hot编码创建新列,指示原始数据中每个可能值的存在(或不存在)。为了理解这一点,我们将通过一个例子来学习。
onehot
在原始数据集中,“颜色”是一个分类变量,有三个类别:“红色”、“黄色”和“绿色”。对应的one-hot编码为每个可能的值包含一列,为原始数据集中的每一行包含一行。如果原始值为“红色”,我们在“红色”列中输入1;如果原始值为“黄色”,则在“黄色”列中输入1,依此类推。
与顺序编码不同,one-hot编码并不假定类别的顺序。因此,如果在分类数据中没有明确的顺序(例如,“红色”既不大于也不小于“黄色”),您可以期望这种方法工作得特别好。我们把没有内在排名的分类变量称为名义变量。
如果类别变量具有大量值(即,通常不会将其用于具有超过15个不同值的变量),则one-hot编码通常不会运行良好。

举例

与上一篇教程一样,我们将使用墨尔本住房数据集。
我们将不关注数据加载步骤。相反,您可以想象,您已经在X_train、X_valid、y_train和y_valid中拥有了训练和验证数据。

import pandas as pd
from sklearn.model_selection import train_test_split

# Read the data
data = pd.read_csv('../input/melbourne-housing-snapshot/melb_data.csv')

# Separate target from predictors
y = data.Price
X = data.drop(['Price'], axis=1)

# Divide data into training and validation subsets
X_train_full, X_valid_full, y_train, y_valid = train_test_split(X, y, train_size=0.8, test_size=0.2,
                                                                random_state=0)

# Drop columns with missing values (simplest approach)
cols_with_missing = [col for col in X_train_full.columns if X_train_full[col].isnull().any()] 
X_train_full.drop(cols_with_missing, axis=1, inplace=True)
X_valid_full.drop(cols_with_missing, axis=1, inplace=True)

# "Cardinality" means the number of unique values in a column
# Select categorical columns with relatively low cardinality (convenient but arbitrary)
low_cardinality_cols = [cname for cname in X_train_full.columns if X_train_full[cname].nunique() < 10 and 
                        X_train_full[cname].dtype == "object"]

# Select numerical columns
numerical_cols = [cname for cname in X_train_full.columns if X_train_full[cname].dtype in ['int64', 'float64']]

# Keep selected columns only
my_cols = low_cardinality_cols + numerical_cols
X_train = X_train_full[my_cols].copy()
X_valid = X_valid_full[my_cols].copy()

我们用下面的head()方法查看一下训练数据。

X_train.head()

'''
	Type	Method	Regionname	Rooms	Distance	Postcode	Bedroom2	Bathroom	Landsize	Lattitude	Longtitude	Propertycount
12167	u	S	Southern Metropolitan	1	5.0	3182.0	1.0	1.0	0.0	-37.85984	144.9867	13240.0
6524	h	SA	Western Metropolitan	2	8.0	3016.0	2.0	2.0	193.0	-37.85800	144.9005	6380.0
8413	h	S	Western Metropolitan	3	12.6	3020.0	3.0	1.0	555.0	-37.79880	144.8220	3755.0
2919	u	SP	Northern Metropolitan	3	13.0	3046.0	3.0	1.0	265.0	-37.70830	144.9158	8870.0
6043	h	S	Western Metropolitan	3	13.3	3020.0	3.0	1.0	673.0	-37.76230	144.8272	4217.0
'''

接下来,我们将获得训练数据中所有分类变量的列表。
我们通过检查每列的数据类型(或数据类型)来实现这一点。object dtype表示一个列有文本(理论上可能有其他内容,但这对我们来说并不重要)。对于该数据集,带有文本的列表示分类变量。

# Get list of categorical variables
s = (X_train.dtypes == 'object')
object_cols = list(s[s].index)

print("Categorical variables:")
print(object_cols)

Categorical variables:
[‘Type’, ‘Method’, ‘Regionname’]

定义衡量每种方法质量的功能

我们定义了一个函数score_dataset()来比较处理分类变量的三种不同方法。此函数报告随机森林模型的平均绝对误差(MAE)。总的来说,我们希望MAE尽可能低!

from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error

# Function for comparing different approaches
def score_dataset(X_train, X_valid, y_train, y_valid):
    model = RandomForestRegressor(n_estimators=100, random_state=0)
    model.fit(X_train, y_train)
    preds = model.predict(X_valid)
    return mean_absolute_error(y_valid, preds)
方法1的得分(删除分类变量)

我们使用select_dtypes()方法删除对象列。

drop_X_train = X_train.select_dtypes(exclude=['object'])
drop_X_valid = X_valid.select_dtypes(exclude=['object'])

print("MAE from Approach 1 (Drop categorical variables):")
print(score_dataset(drop_X_train, drop_X_valid, y_train, y_valid))

MAE from Approach 1 (Drop categorical variables):
175703.48185157913

方法2的得分(顺序编码)

Scikit-learn有一个OrdinalCoder类,可用于获取顺序编码。我们在分类变量上循环,并对每个列分别应用顺序编码器。

from sklearn.preprocessing import OrdinalEncoder

# Make copy to avoid changing original data 
label_X_train = X_train.copy()
label_X_valid = X_valid.copy()

# Apply ordinal encoder to each column with categorical data
ordinal_encoder = OrdinalEncoder()
label_X_train[object_cols] = ordinal_encoder.fit_transform(X_train[object_cols])
label_X_valid[object_cols] = ordinal_encoder.transform(X_valid[object_cols])

print("MAE from Approach 2 (Ordinal Encoding):") 
print(score_dataset(label_X_train, label_X_valid, y_train, y_valid))

MAE from Approach 2 (Ordinal Encoding):
165936.40548390493

在上面的代码单元中,对于每一列,我们将每个唯一的值随机分配给不同的整数。这是一种比提供自定义标签更简单的常见方法;然而,如果我们为所有序数变量提供更好的信息标签,我们可以期待性能的进一步提升。

方法3的分数(one-hot编码)

我们使用scikit-learn中的OneHotEncoder类学习获取one-hot编码。有许多参数可用于自定义其行为。

  • 我们设置handle_unknown='ignore'以避免验证数据包含训练数据中未表示的类时出错,以及
  • 设置sparse=False可确保编码的列作为numpy数组(而不是稀疏矩阵)返回。

为了使用编码器,我们只提供我们想要进行one-hot编码的分类列。例如,为了对训练数据进行编码,我们提供了X_train[object_cols]。(下面代码单元中的object_cols是带有分类数据的列名列表,因此X_train[object_cols]包含训练集中的所有分类数据。)

from sklearn.preprocessing import OneHotEncoder

# Apply one-hot encoder to each column with categorical data
OH_encoder = OneHotEncoder(handle_unknown='ignore', sparse=False)
OH_cols_train = pd.DataFrame(OH_encoder.fit_transform(X_train[object_cols]))
OH_cols_valid = pd.DataFrame(OH_encoder.transform(X_valid[object_cols]))

# One-hot encoding removed index; put it back
OH_cols_train.index = X_train.index
OH_cols_valid.index = X_valid.index

# Remove categorical columns (will replace with one-hot encoding)
num_X_train = X_train.drop(object_cols, axis=1)
num_X_valid = X_valid.drop(object_cols, axis=1)

# Add one-hot encoded columns to numerical features
OH_X_train = pd.concat([num_X_train, OH_cols_train], axis=1)
OH_X_valid = pd.concat([num_X_valid, OH_cols_valid], axis=1)

print("MAE from Approach 3 (One-Hot Encoding):") 
print(score_dataset(OH_X_train, OH_X_valid, y_train, y_valid))

MAE from Approach 3 (One-Hot Encoding):
166089.4893009678

哪种方法最好?

在这种情况下,删除分类列(方法1)表现最差,因为它有最高的MAE分数。至于其他两种方法,由于返回的MAE分数在价值上非常接近,因此不能说明一种方法比另一种方法要好。

一般来说,one-hot编码(方法3)的性能通常最好,删除分类列(方法1)的性能通常最差,但具体情况会有所不同。

结论

世界上充斥着分类数据。如果你知道如何使用这种常见的数据类型,你将成为一名更有效的数据科学家!

轮到你了

在练习中运用你的新技能!


练习部分

通过编码分类变量,您将获得迄今为止最好的结果!

设置

下面的问题将为你的工作提供反馈。运行以下单元格设置反馈系统。

import os
if not os.path.exists("../input/train.csv"):
    os.symlink("../input/home-data-for-ml-course/train.csv", "../input/train.csv")  
    os.symlink("../input/home-data-for-ml-course/test.csv", "../input/test.csv") 
from learntools.core import binder
binder.bind(globals())
from learntools.ml_intermediate.ex3 import *
print("Setup Complete")

Setup Complete

在本练习中,您将使用 Housing Prices Competition for Kaggle Learn Users 案例.

banner

在不做任何更改的情况下运行以下代码单元,以加载X_train、X_valid、y_train和y_valid中的训练集和验证集。测试集在X_test中加载。

import pandas as pd
from sklearn.model_selection import train_test_split

# Read the data
# 读取数据
X = pd.read_csv('../input/train.csv', index_col='Id') 
X_test = pd.read_csv('../input/test.csv', index_col='Id')

# Remove rows with missing target, separate target from predictors
X.dropna(axis=0, subset=['SalePrice'], inplace=True)
y = X.SalePrice
X.drop(['SalePrice'], axis=1, inplace=True)

# To keep things simple, we'll drop columns with missing values
# 删除目标值缺失的列,从预测中分享目标
cols_with_missing = [col for col in X.columns if X[col].isnull().any()] 
X.drop(cols_with_missing, axis=1, inplace=True)
X_test.drop(cols_with_missing, axis=1, inplace=True)

# Break off validation set from training data
# 从训练集中分离出验证数据
X_train, X_valid, y_train, y_valid = train_test_split(X, y,
                                                      train_size=0.8, test_size=0.2,
                                                      random_state=0)

使用以下代码打印数据的前五行。查看数据各列的情况

X_train.head()

请注意,数据集包含数字变量和分类变量。在训练模型之前,需要对分类数据进行编码。
要比较不同的模型,您将使用教程中相同的score_dataset()函数。此函数报告随机森林模型的平均绝对误差(MAE)。

from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error

# function for comparing different approaches
def score_dataset(X_train, X_valid, y_train, y_valid):
    model = RandomForestRegressor(n_estimators=100, random_state=0)
    model.fit(X_train, y_train)
    preds = model.predict(X_valid)
    return mean_absolute_error(y_valid, preds)

第1步:删除包含分类数据的列

您将从最简单的方法开始。使用下面的代码单元预处理X_train中的数据,并使用X_valid删除包含分类数据的列。将预处理的数据集分别命名为drop_X_train和drop_X_valid。

# Fill in the lines below: drop columns in training and validation data
drop_X_train = ____
drop_X_valid = ____
​
# Check your answers
step_1.check()

运行下一个代码单元以获取此方法的MAE。

print("MAE from Approach 1 (Drop categorical variables):")
print(score_dataset(drop_X_train, drop_X_valid, y_train, y_valid))

MAE from Approach 1 (Drop categorical variables):
17837.82570776256

在开始顺序编码之前,我们将研究数据集。具体来说,我们将查看“Condition2”列。下面的代码单元打印训练集和验证集中的唯一条目。

print("Unique values in 'Condition2' column in training data:", X_train['Condition2'].unique())
print("\nUnique values in 'Condition2' column in validation data:", X_valid['Condition2'].unique())

Unique values in ‘Condition2’ column in training data: [‘Norm’ ‘PosA’ ‘Feedr’ ‘PosN’ ‘Artery’ ‘RRAe’]

Unique values in ‘Condition2’ column in validation data: [‘Norm’ ‘RRAn’ ‘RRNn’ ‘Artery’ ‘Feedr’ ‘PosN’]

第2步:顺序编码

A 部分

如果您现在将代码编写到:

  • 在训练数据中安装顺序编码器,然后
  • 使用它转换培训和验证数据,

你会出错的。你能明白为什么会这样吗?(您需要使用上述输出来回答此问题。)

将顺序编码器拟合到训练数据中的列,会为训练数据中出现的每个唯一值创建相应的整数值标签。如果验证数据包含的值也没有出现在训练数据中,编码器将抛出一个错误,因为这些值不会被分配一个整数。请注意,验证数据中的“Condition2”列包含值“RRAn”和“RRNn”,但这些值不会出现在训练数据中——因此,如果我们尝试使用带有scikit-learn的顺序编码器,代码将抛出错误。

这是现实数据中常见的问题,有很多方法可以解决这个问题。例如,您可以编写一个自定义序号编码器来处理新类别。然而,最简单的方法是删除有问题的分类列。

运行下面的代码单元格,将有问题的列保存到bad_label_cols列表中。同样,可以安全顺序编码的列保存在good_label_cols列表中。

# Categorical columns in the training data
object_cols = [col for col in X_train.columns if X_train[col].dtype == "object"]

# Columns that can be safely ordinal encoded
good_label_cols = [col for col in object_cols if 
                   set(X_valid[col]).issubset(set(X_train[col]))]
        
# Problematic columns that will be dropped from the dataset
bad_label_cols = list(set(object_cols)-set(good_label_cols))
        
print('Categorical columns that will be ordinal encoded:', good_label_cols)
print('\nCategorical columns that will be dropped from the dataset:', bad_label_cols)

Categorical columns that will be ordinal encoded: [‘MSZoning’, ‘Street’, ‘LotShape’, ‘LandContour’, ‘Utilities’, ‘LotConfig’, ‘LandSlope’, ‘Neighborhood’, ‘Condition1’, ‘BldgType’, ‘HouseStyle’, ‘RoofStyle’, ‘Exterior1st’, ‘Exterior2nd’, ‘ExterQual’, ‘ExterCond’, ‘Foundation’, ‘Heating’, ‘HeatingQC’, ‘CentralAir’, ‘KitchenQual’, ‘PavedDrive’, ‘SaleType’, ‘SaleCondition’]

Categorical columns that will be dropped from the dataset: [‘Condition2’, ‘RoofMatl’, ‘Functional’]

B 部分

使用下一个代码单元对X_train和X_valid中的数据进行顺序编码。将预处理的数据集分别命名为label_X_train和label_X_valid。

我们在下面提供了从数据集中删除bad_label_cols中的分类列的代码。

你应该用好的标签对分类列进行顺序编码。

from sklearn.preprocessing import OrdinalEncoder

# Drop categorical columns that will not be encoded
label_X_train = X_train.drop(bad_label_cols, axis=1)
label_X_valid = X_valid.drop(bad_label_cols, axis=1)

# Apply ordinal encoder 
____ # Your code here
    
# Check your answer
step_2.b.check()
print("MAE from Approach 2 (Ordinal Encoding):") 
print(score_dataset(label_X_train, label_X_valid, y_train, y_valid))

MAE from Approach 2 (Ordinal Encoding):
17098.01649543379

到目前为止,您已经尝试了两种不同的方法来处理分类变量。而且,您已经看到,编码分类数据比从数据集中删除列产生更好的结果。
很快,您将尝试one-hot编码。在此之前,我们还需要讨论一个话题。首先运行下一个代码单元,不做任何更改。

# Get number of unique entries in each column with categorical data
object_nunique = list(map(lambda col: X_train[col].nunique(), object_cols))
d = dict(zip(object_cols, object_nunique))

# Print number of unique entries by column, in ascending order
sorted(d.items(), key=lambda x: x[1])

[(‘Street’, 2),
(‘Utilities’, 2),
(‘CentralAir’, 2),
(‘LandSlope’, 3),
(‘PavedDrive’, 3),
(‘LotShape’, 4),
(‘LandContour’, 4),
(‘ExterQual’, 4),
(‘KitchenQual’, 4),
(‘MSZoning’, 5),
(‘LotConfig’, 5),
(‘BldgType’, 5),
(‘ExterCond’, 5),
(‘HeatingQC’, 5),
(‘Condition2’, 6),
(‘RoofStyle’, 6),
(‘Foundation’, 6),
(‘Heating’, 6),
(‘Functional’, 6),
(‘SaleCondition’, 6),
(‘RoofMatl’, 7),
(‘HouseStyle’, 8),
(‘Condition1’, 9),
(‘SaleType’, 9),
(‘Exterior1st’, 15),
(‘Exterior2nd’, 16),
(‘Neighborhood’, 25)]

第3步:调查基数

A 部分

上面的输出显示了每个包含分类数据的列中唯一值的数量。例如,训练数据中的“Street”列有两个唯一的值:“Grvl”和“Pave”,分别对应于碎石路和铺砌路。
我们将一个分类变量的唯一项的数量称为该分类变量的基数。例如,“Street”变量的基数为2。
使用以上输出回答以下问题。

# Fill in the line below: How many categorical variables in the training data
# have cardinality greater than 10?
high_cardinality_numcols = ____

# Fill in the line below: How many columns are needed to one-hot encode the 
# 'Neighborhood' variable in the training data?
num_cols_neighborhood = ____

# Check your answers
step_3.a.check()
B 部分

对于具有多行的大型数据集,one-hot编码可以极大地扩展数据集的大小。因此,我们通常只对一个基数相对较低的列进行one-hot编码。然后,高基数列可以从数据集中删除,也可以使用顺序编码。

例如,考虑一个包含10000行的数据集,其中包含一个包含100个唯一条目的分类列。

  • 如果此列替换为相应的热编码,则会向数据集添加多少个条目?
  • 如果我们用顺序编码替换列,会添加多少个条目?
    用你的答案填写以下几行。
# Fill in the line below: How many entries are added to the dataset by 
# replacing the column with a one-hot encoding?
OH_entries_added = ____

# Fill in the line below: How many entries are added to the dataset by
# replacing the column with an ordinal encoding?
# 填写以下行
label_entries_added = ____

# Check your answers
step_3.b.check()

接下来,您将尝试one-hot编码。但是,您将只为基数小于10的列创建one-hot编码,而不是对数据集中的所有分类变量进行编码。

在不做任何更改的情况下运行下面的代码单元格,将low_cardinality_cols设置为一个Python列表,其中包含将被one-hot编码的列。同样,high_cardinality_cols包含将从数据集中删除的分类列列表。

# Columns that will be one-hot encoded
# 进行one-hot 编码列
low_cardinality_cols = [col for col in object_cols if X_train[col].nunique() < 10]

# Columns that will be dropped from the dataset
# 删除数据集相关的列
high_cardinality_cols = list(set(object_cols)-set(low_cardinality_cols))

print('Categorical columns that will be one-hot encoded:', low_cardinality_cols)
print('\nCategorical columns that will be dropped from the dataset:', high_cardinality_cols)

Categorical columns that will be one-hot encoded: [‘MSZoning’, ‘Street’, ‘LotShape’, ‘LandContour’, ‘Utilities’, ‘LotConfig’, ‘LandSlope’, ‘Condition1’, ‘Condition2’, ‘BldgType’, ‘HouseStyle’, ‘RoofStyle’, ‘RoofMatl’, ‘ExterQual’, ‘ExterCond’, ‘Foundation’, ‘Heating’, ‘HeatingQC’, ‘CentralAir’, ‘KitchenQual’, ‘Functional’, ‘PavedDrive’, ‘SaleType’, ‘SaleCondition’]

Categorical columns that will be dropped from the dataset: [‘Exterior2nd’, ‘Exterior1st’, ‘Neighborhood’]

第4步:One-hot 编码

使用下一个代码单元对X_train和X_valid中的数据进行one-hot编码。将预处理的数据帧分别命名为OH_X_train和OH_X_valid。

数据集中分类列的完整列表可以在Python列表object_cols中找到。

你应该只对低基数的分类列进行一次one-hot编码。所有其他分类列都应从数据集中删除。

from sklearn.preprocessing import OneHotEncoder

# Use as many lines of code as you need!
# 需要多行的代码
OH_X_train = ____ # Your code here
OH_X_valid = ____ # Your code here

# Check your answer
step_4.check()

运行下一个代码单元以获取此方法的MAE。

print("MAE from Approach 3 (One-Hot Encoding):") 
print(score_dataset(OH_X_train, OH_X_valid, y_train, y_valid))

MAE from Approach 3 (One-Hot Encoding):
17525.345719178084

生成测试预测并提交结果

完成第4步后,如果您想使用所学知识将结果提交到排行榜,则需要在生成预测之前对测试数据进行预处理。
这一步完全是可选的,你不需要将结果提交到排行榜就可以成功完成练习。
如果您需要帮助记住如何参加比赛或将结果保存到CSV,请查看上一个练习。生成包含结果的文件后,请按照以下说明操作:

  • 首先单击窗口右上角的“保存版本”按钮。这将生成一个弹出窗口。
  • 确保选择了“全部保存并运行”选项,然后单击“保存”按钮。
  • 这将在笔记本的左下角生成一个窗口。完成运行后,单击“保存版本”按钮右侧的数字。这会在屏幕右侧显示一个版本列表。点击省略号(…)在最新版本的右侧,选择“在查看器中打开”。这将使您进入同一页面的查看模式。您需要向下滚动才能返回这些说明。
  • 单击屏幕右侧的“输出”选项卡。然后,点击你想提交的文件,点击提交按钮,将结果提交到排行榜。

您现在已成功提交竞赛!

如果您想继续工作以提高性能,请选择屏幕右上角的编辑按钮。然后您可以更改代码并重复该过程。还有很大的改进空间,你将在工作中登上排行榜。

答案

### step 1
# Drop columns in training and validation data
drop_X_train = X_train.select_dtypes(exclude=['object'])
drop_X_valid = X_valid.select_dtypes(exclude=['object'])

# step 2
# Drop categorical columns that will not be encoded
label_X_train = X_train.drop(bad_label_cols, axis=1)
label_X_valid = X_valid.drop(bad_label_cols, axis=1)

# Apply ordinal encoder
ordinal_encoder = OrdinalEncoder()
label_X_train[good_label_cols] = ordinal_encoder.fit_transform(X_train[good_label_cols])
label_X_valid[good_label_cols] = ordinal_encoder.transform(X_valid[good_label_cols])

# step 3
# How many categorical variables in the training data
# have cardinality greater than 10?
high_cardinality_numcols = 3

# How many columns are needed to one-hot encode the
# 'Neighborhood' variable in the training data?
num_cols_neighborhood = 25

# How many entries are added to the dataset by
# replacing the column with a one-hot encoding?
OH_entries_added = 1e4*100 - 1e4

# How many entries are added to the dataset by
# replacing the column with an ordinal encoding?
label_entries_added = 0

# step 4
# Apply one-hot encoder to each column with categorical data
OH_encoder = OneHotEncoder(handle_unknown='ignore', sparse=False)
OH_cols_train = pd.DataFrame(OH_encoder.fit_transform(X_train[low_cardinality_cols]))
OH_cols_valid = pd.DataFrame(OH_encoder.transform(X_valid[low_cardinality_cols]))

# One-hot encoding removed index; put it back
OH_cols_train.index = X_train.index
OH_cols_valid.index = X_valid.index

# Remove categorical columns (will replace with one-hot encoding)
num_X_train = X_train.drop(object_cols, axis=1)
num_X_valid = X_valid.drop(object_cols, axis=1)

# Add one-hot encoded columns to numerical features
OH_X_train = pd.concat([num_X_train, OH_cols_train], axis=1)
OH_X_valid = pd.concat([num_X_valid, OH_cols_valid], axis=1)
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值