我有一个混合类型列的熊猫数据框架,我想应用sklearn的min_max_scaler到一些列。理想情况下,我希望在适当的地方进行这些转换,但还没有找到实现这些转换的方法。我写了下面的工作代码:
import pandas as pd
import numpy as np
from sklearn import preprocessing
scaler = preprocessing.MinMaxScaler()
dfTest = pd.DataFrame({'A':[14.00,90.20,90.95,96.27,91.21],'B':[103.02,107.26,110.35,114.23,114.68], 'C':['big','small','big','small','small']})
min_max_scaler = preprocessing.MinMaxScaler()
def scaleColumns(df, cols_to_scale):
for col in cols_to_scale:
df[col] = pd.DataFrame(min_max_scaler.fit_transform(pd.DataFrame(dfTest[col])),columns=[col])
return df
dfTest
A B C
0 14.00 103.02 big
1 90.20 107.26 small
2 90.95 110.35 big
3 96.27 114.23 small
4 91.21 114.68 small
scaled_df = scaleColumns(dfTest,['A','B'])
scaled_df
A B C
0 0.000000 0.000000 big
1 0.926219 0.363636 small
2 0.935335 0.628645 big
3 1.000000 0.961407 small
4 0.938495 1.000000 small
我很好奇这是否是做这个变换的首选/最有效的方法。是否可以用df。应用会更好吗?
我也很惊讶我不能得到以下代码的工作:
bad_output = min_max_scaler.fit_transform(dfTest['A'])
如果我把整个数据帧传递给缩放器,它可以工作:
dfTest2 = dfTest.drop('C', axis = 1)
good_output = min_max_scaler.fit_transform(dfTest2)
good_output
我很困惑为什么传递一个级数给标量失败。在我上面的完整工作代码中,我希望只是将一个系列传递给缩放器,然后将dataframe column =设置为缩放系列。
正如在pir的评论中提到的那样- .apply(lambda el: scale.fit_transform(el))方法将产生以下警告:
DeprecationWarning:在0.17中,将1d数组作为数据传递已弃用
并将在0.19中引发ValueError。重塑您的数据或使用
x .重塑(- 1,1)(如果数据只有一个特征)或x .重塑(1,-1)
如果它只包含一个样本。
将你的列转换为numpy数组应该做的工作(我更喜欢StandardScaler):
from sklearn.preprocessing import StandardScaler
scale = StandardScaler()
dfTest[['A','B','C']] = scale.fit_transform(dfTest[['A','B','C']].as_matrix())
-编辑2018年11月(熊猫0.23.4测试)-
正如Rob Murray在评论中提到的,在当前(v0.23.4)版本的pandas .as_matrix()中返回FutureWarning。因此,它应该被.values替换:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit_transform(dfTest[['A','B']].values)
-编辑2019年5月(测试熊猫0.24.2)-
正如joelostblom在评论中提到的,“从0.24.0开始,建议使用.to_numpy()而不是.values。”
更新的例子:
import pandas as pd
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
dfTest = pd.DataFrame({
'A':[14.00,90.20,90.95,96.27,91.21],
'B':[103.02,107.26,110.35,114.23,114.68],
'C':['big','small','big','small','small']
})
dfTest[['A', 'B']] = scaler.fit_transform(dfTest[['A','B']].to_numpy())
dfTest
A B C
0 -1.995290 -1.571117 big
1 0.436356 -0.603995 small
2 0.460289 0.100818 big
3 0.630058 0.985826 small
4 0.468586 1.088469 small
我不确定以前版本的pandas是否阻止了这一点,但现在下面的代码片段非常适合我,并且生成了您想要的东西,而不必使用apply
>>> import pandas as pd
>>> from sklearn.preprocessing import MinMaxScaler
>>> scaler = MinMaxScaler()
>>> dfTest = pd.DataFrame({'A':[14.00,90.20,90.95,96.27,91.21],
'B':[103.02,107.26,110.35,114.23,114.68],
'C':['big','small','big','small','small']})
>>> dfTest[['A', 'B']] = scaler.fit_transform(dfTest[['A', 'B']])
>>> dfTest
A B C
0 0.000000 0.000000 big
1 0.926219 0.363636 small
2 0.935335 0.628645 big
3 1.000000 0.961407 small
4 0.938495 1.000000 small
像这样的吗?
dfTest = pd.DataFrame({
'A':[14.00,90.20,90.95,96.27,91.21],
'B':[103.02,107.26,110.35,114.23,114.68],
'C':['big','small','big','small','small']
})
dfTest[['A','B']] = dfTest[['A','B']].apply(
lambda x: MinMaxScaler().fit_transform(x))
dfTest
A B C
0 0.000000 0.000000 big
1 0.926219 0.363636 small
2 0.935335 0.628645 big
3 1.000000 0.961407 small
4 0.938495 1.000000 small