Python - SkLearn Imputer用法

6
我有以下问题:我有一个pandas数据框,其中缺失值用字符串na标记。我想在它上面运行Imputer,将缺失的值替换为该列中的平均值。根据sklearn的文档,参数missing_values应该帮助我完成这个任务:

missing_values:整数或“NaN”,可选(默认值=“NaN”)缺失值的占位符。所有缺失值的出现都将被填充。对于编码为np.nan的缺失值,请使用字符串值“NaN”。

据我理解,这意味着如果我写
df = pd.read_csv(filename)
imp = Imputer(missing_values='na')
imp.fit_transform(df)

这意味着imputer会将数据框中所有的na值替换为该列的平均值。然而,实际上我遇到了错误:
ValueError: could not convert string to float: na

我误解了什么?这不是填充器应该工作的方式吗?那我怎样才能用平均值替换na字符串呢?我应该使用lambda表达式吗?
谢谢!
4个回答

4

既然你说要用该列的均值去替换这些'na',我猜测缺失值实际上是浮点数。问题在于pandas无法识别字符串'na'作为缺失值,因此会将该列读取为object类型,而不是某种float类型。

例如,考虑以下.csv文件:

 test.csv

 col1,col2
 1.0,1.0
 2.0,2.0
 3.0,3.0
 na,4.0
 5.0,5.0

使用简单的导入语句df = pd.read_csv('test.csv'), df.dtypes告诉我们col1object类型,而col2float64类型。但是如何计算一系列对象的均值呢?

解决方案是告诉pd.read_csv()将字符串'na'解释为缺失值:

df = pd.read_csv('test.csv', na_values='na')

生成的数据框中包含两列float64类型,您现在可以使用您的填充器。

0

这是我收到的错误信息

IndexError:将来,0维布尔数组将被解释为有效的布尔索引

在我的情况下,我遇到了“中位数”策略的问题,将其更改为平均值或最常见的策略即可解决。


0

首先导入 pandas,然后读取 your_file_name.csv 文件。而 iloc 是由 pandas.DataFrame.iloc 定义的,它是纯整数位置索引。这里的格式是 iloc[行索引,列索引],其中 a、b、c、d 都是整数,ab、c、d 也可以为空。

import pandas as pd
dataSet = pd.read_csv('your_file_name.csv')
X = dataSet.iloc[ a:b , c:d].values

如果你不使用 .values ,那么你将无法在 imputer 转换中使用它。
在导入 Imputer 后,定义您的 Imputer 参数 missing_values =
"要替换的数据中的缺失值",strategy ="mean"(还有两个更多的策略,即 median 和 dataSet 中最频繁出现的值,但默认值为 mean。然后设置 axis = (0 用于列和 1 用于行),其他是 copy 和 verbose)你可以在上面阅读更多关于它的内容。

from sklearn.preprocessing import Imputer
i = Imputer(missing_values="NaN", strategy="mean", axis=0) 

将数据适配到您定义的Imputer方式中,然后使用transform方法进行转换。这将返回对象数据类型的数组。

i  = i.fit(X[a:b, c:d])
X[a:b, c:d ] = i.transform(X[a:b,c:d])

请记住,您选择的列应仅包含浮点或整数类型的值,否则可能会显示错误,无法将字符串转换为浮点数


0

这里有几件事情需要注意。

确保您不要在“object”类型或分类变量上输入,您可以像这样查看您的数据:

df = pd.read_csv(filename)

print(df.info(null_counts=True))

最后一列应该是类型。

让我们看一个例子:

df = pd.DataFrame({'A' : [1, 2, 2, 2, 'NaN', 3, 4, 5, 6], 'B' : [3, 3, 'NaN', 3, 3, 4, 3, 3, 3]})

输出:

df.head()


    A   B
---------
0   1   3
1   2   3
2   2   NaN
3   2   3
4   NaN 3

现在让我们来看一下类型。
df.info(null_counts=True)

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 9 entries, 0 to 8
Data columns (total 2 columns):
0    9 non-null float64
1    9 non-null float64
dtypes: float64(2)
memory usage: 224.0 bytes

现在输入中:

from sklearn.preprocessing import Imputer
imputer = Imputer(missing_values='NaN', strategy='most_frequent', axis=0)
df_imputed = pd.DataFrame(imputer.fit_transform(df))
df_imputed.head()


    0   1
-----------
0   1.0 3.0
1   2.0 3.0
2   2.0 3.0
3   2.0 3.0
4   2.0 3.0

现在这很好,但不能在分类(类型对象/字符串)上完成

处理它的一种方法是将分类特征更改为数字,类似于这样:

df_with_cat = pd.DataFrame({'A': ['ios', 'android', 'web', 'NaN'], 'B' : [4, 4, 'NaN', 2]})
df_with_cat.head()


      A     B
-------------
0   ios     4
1   android 4
2   web     NaN
3   NaN     2

和信息

df_with_cat.info(null_counts=True)

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 2 columns):
A    4 non-null object
B    4 non-null object
dtypes: object(2)
memory usage: 144.0+ bytes

我们确定B是数字,所以让我们这样做:

df_with_cat['B'] = df_with_cat['B'].astype(np.float)
df_with_cat.info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 2 columns):
A    4 non-null object
B    3 non-null float64
dtypes: float64(1), object(1)
memory usage: 144.0+ bytes

如果我们使用上面的那个填充器,会出现错误(你可以试一下)。
现在让我们将“A”类别转换为数字:
CATEGORICAL_FEATURES = [
    'A', 
]
data_dum = pd.get_dummies(df_with_cat, columns=['A'], drop_first=True)
data_dum.head()

    B   A_android   A_ios   A_web
---------------------------------
0   4       0         1       0
1   4       1         0       0
2   NaN     0         0       1
3   2       0         0       0

现在我们可以在数据框上运行与上面完全相同的Imputer


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接