01 缺失值处理
在缺失值的处理上,主要配合使用 sklearn.preprocessing 中的Imputer类、Pandas和Numpy。其中由于Pandas对于数据探索、分析和探查的支持较为良好,因此围绕Pandas的缺失值处理较为常用。
1. 导入库
该代码示例中用到Pandas、Numpy和sklearn。
import pandas as pd # 导入Pandas库
import numpy as np # 导入numpy库
from sklearn.preprocessing import Imputer # 导入sklearn.preprocessing中的Imputer库
2. 生成缺失数据
# 生成缺失数据
df = pd.DataFrame(np.random.randn(6, 4), columns=['col1', 'col2', 'col3', 'col4']) # 生成一份数据
df.iloc[1:2, 1] = np.nan # 增加缺失值
df.iloc[4, 3] = np.nan # 增加缺失值
print(df)
通过Pandas生成一个6行4列,列名分别为'col1'、'col2'、'col3'、'col4'的数据框。同时,数据框中增加两个缺失值数据。
除了示例中直接通过pd.DataFrame来直接创建数据框外,还可以使用数据框对象的 df.from_records、df.from_dict、df.from_items 来从元组记录、字典和键值对对象创建数据框,或使用pandas.read_csv、pandas.read_table、pandas.read_clipboard 等方法读取文件或剪贴板创建数据框。该代码段执行后返回了定义含有缺失值的数据框,结果如下:
col1 col2 col3 col4
0 -0.112415 -0.768180 -0.084859 0.296691
1 -1.777315 NaN -0.166615 -0.628756
2 -0.629461 1.892790 -1.850006 0.157567
3 0.544860 -1.230804 0.836615 -0.945712
4 0.703394 -0.764552 -1.214379 NaN
5 1.928313 -1.376593 -1.557721 0.289643
提示:由于生成的数据是随机产生的,因此读者的实际结果可能与上述结果不一致。
3. 判断缺失值
# 查看哪些值缺失
nan_all = df.isnull() # 获得所有数据框中的N值
print(nan_all) # 打印输出
# 查看哪些列缺失
nan_col1 = df.isnull().any() # 获得含有NA的列
nan_col2 = df.isnull().all() # 获得全部为NA的列
print(nan_col1) # 打印输出
print(nan_col2) # 打印输出
通过 df.null() 方法找到所有数据框中的缺失值(默认缺失值是 NaN 格式),然后使用 any() 或 all() 方法来查找含有至少1个或全部缺失值的列,其中 any() 方法用来返回指定轴中的任何元素为 True,而 all() 方法用来返回指定轴的所有元素都为 True。该代码段执行后返回如下结果。
判断元素是否是缺失值(第2行第2列和第5行第4列):
col1 col2 col3 col4
0 False False False False
1 False True False False
2 False False False False
3 False False False False
4 False False False True
5 False False False False
列出至少有一个元素含有缺失值的列(该示例中为col2和col4):
col1 False
col2 True
col3 False
col4 True
dtype: bool
列出全部元素含有缺失值的列(该示例中没有):
col1 False
col2 False
col3 False
col4 False
dtype: bool
4. 丢弃缺失值
df2 = df.dropna() # 直接丢弃含有NA的行记录
print(df2) # 打印输出
通过Pandas默认的 dropna() 方法丢弃缺失值,返回无缺失值的数据记录。该代码段执行后返回如下结果(第2行、第5行数据记录被删除):
col1 col2 col3 col4
0 -0.112415 -0.768180 -0.084859 0.296691
2 -0.629461 1.892790 -1.850006 0.157567
3 0.544860 -1.230804 0.836615 -0.945712
5 1.928313 -1.376593 -1.557721 0.289643
5. 通过sklearn的数据预处理方法对缺失值进行处理
nan_model = Imputer(missing_values='NaN', strategy='mean', axis=0) # 建立替换规则:将值为NaN的缺失值以均值做替换
nan_result = nan_model.fit_transform(df) # 应用模型规则
print(nan_result) # 打印输出
首先通过 Imputer 方法创建一个预处理对象,其中 missing_values 为默认缺失值的字符串,默认为 NaN;示例中选择缺失值替换方法是均值(默认),还可以选择使用中位数和众数进行替换,即 strategy 值设置为 median 或 most_frequent;后面的参数 axis 用来设置输入的轴,默认值为0,即使用列做计算逻辑。
然后使用预处理对象的 fit_transform 方法对 df(数据框对象)进行处理,该方法是将 fit 和 transform 组合起来使用。代码执行后返回如下结果:
[[-0.11241503 -0.76818022 -0.08485904 0.29669147]
[-1.77731513 -0.44946793 -0.16661458 -0.62875601]
[-0.62946127 1.89278959 -1.85000643 0.15756702]
[ 0.54486026 -1.23080434 0.836615 -0.9457117 ]
[ 0.70339369 -0.76455205 -1.21437918 -0.16611331]
[ 1.92831315 -1.37659263 -1.55772092 0.28964265]]
代码中的第2行第2列和第5行第4列分别被各自列的均值替换。为了验证,我们手动计算一下各自列的均值,通过使用 df['col2'].mean() 和 df['col4'].mean() 分别获得这两列的均值为-0.4494679289032068和-0.16611331259664791,与sklearn返回的结果一致。
6. 使用Pandas做缺失值处理
nan_result_pd1 = df.fillna(method='backfill') # 用后面的值替换缺失值
nan_result_pd2 = df.fillna(method='bfill', limit=1) # 用后面的值替代缺失值,限制每列只能替代一个缺失值
nan_result_pd3 = df.fillna(method='pad') # 用前面的值替换缺失值
nan_result_pd4 = df.fillna(0) # 用0替换缺失值
nan_result_pd5 = df.fillna({'col2': 1.1, 'col4': 1.2}) # 用不同值替换不同列的缺失值
nan_result_pd6 = df.fillna(df.mean()['col2':'col4']) # 用各自列的平均数替换缺失值
# 打印输出
print(nan_result_pd1) # 打印输出
print(nan_result_pd2) # 打印输出
print(nan_result_pd3) # 打印输出
print(nan_result_pd4) # 打印输出
print(nan_result_pd5) # 打印输出
print(nan_result_pd6) # 打印输出
Pandas对缺失值的处理方法是 df.fillna(),该方法中最主要的两个参数是value 和 method。前者通过固定(或手动指定)的值替换缺失值,后者使用Pandas提供的默认方法替换缺失值。以下是 method 支持的方法。
在示例中, nan_result_pd4、nan_result_pd5、nan_result_pd6 分别使用0、不同的值、平均数替换缺失值。需要注意的是,如果要使用不同具体值替换,需要使用 scalar、dict、SerIEs 或 DataFrame 的格式定义。
上述代码执行后返回如下结果。
用后面的值(method='backfill')替换缺失值:
col1 col2 col3 col4
0 -0.112415 -0.768180 -0.084859 0.296691
1 -1.777315 1.892790 -0.166615 -0.628756
2 -0.629461 1.892790 -1.850006 0.157567
3 0.544860 -1.230804 0.836615 -0.945712
4 0.703394 -0.764552 -1.214379 0.289643
5 1.928313 -1.376593 -1.557721 0.289643
用后面的值(method='bfill', limit = 1)替换缺失值:
col1 col2 col3 col4
0 -0.112415 -0.768180 -0.084859 0.296691
1 -1.777315 1.892790 -0.166615 -0.628756
2 -0.629461 1.892790 -1.850006 0.157567
3 0.544860 -1.230804 0.836615 -0.945712
4 0.703394 -0.764552 -1.214379 0.289643
5 1.928313 -1.376593 -1.557721 0.289643
用前面的值替换缺失值(method='pad'):
col1 col2 col3 col4
0 -0.112415 -0.768180 -0.084859 0.296691
1 -1.777315 -0.768180 -0.166615 -0.628756
2 -0.629461 1.892790 -1.850006 0.157567
3 0.544860 -1.230804 0.836615 -0.945712
4 0.703394 -0.764552 -1.214379 -0.945712
5 1.928313 -1.376593 -1.557721 0.289643
用0替换缺失值:
col1 col2 col3 col4
0 -0.112415 -0.768180 -0.084859 0.296691
1 -1.777315 0.000000 -0.166615 -0.628756
2 -0.629461 1.892790 -1.850006 0.157567
3 0.544860 -1.230804 0.836615 -0.945712
4 0.703394 -0.764552 -1.214379 0.000000
5 1.928313 -1.376593 -1.557721 0.289643
手动指定两个缺失值分布为1.1和1.2:
col1 col2 col3 col4
0 -0.112415 -0.768180 -0.084859 0.296691
1 -1.777315 1.100000 -0.166615 -0.628756
2 -0.629461 1.892790 -1.850006 0.157567
3 0.544860 -1.230804 0.836615 -0.945712
4 0.703394 -0.764552 -1.214379 1.200000
5 1.928313 -1.376593 -1.557721 0.289643
用平均数代替,选择各自列的均值替换缺失值:
col1 col2 col3 col4
0 -0.112415 -0.768180 -0.084859 0.296691
1 -1.777315 -0.449468 -0.166615 -0.628756
2 -0.629461 1.892790 -1.850006 0.157567
3 0.544860 -1.230804 0.836615 -0.945712
4 0.703394 -0.764552 -1.214379 -0.166113
5 1.928313 -1.376593 -1.557721 0.289643
以上示例中,直接指定 method 的方法适用于大多数情况,较为简单直接;但使用value 的方法则更为灵活,原因是可以通过函数的形式将缺失值的处理规则写好,然后直接赋值即可。限于篇幅,不对所有方法做展开讲解。
另外,如果是直接替换为特定值的应用,也可以考虑使用Pandas的 replace 功能。本示例的 df (原始数据框)可直接使用 df.replace(np.nan,0),这种用法更加简单粗暴,但也能达到效果。当然,replace的出现是为了解决各种替换应用的,缺失值只是其中的一种应用而已。
上述过程中,主要需要考虑的关键点是缺失值的替换策略,可指定多种方法替换缺失值,具体根据实际需求而定,但大多数情况下均值、众数和中位数的方法较为常用。如果场景固定,也可以使用特定值(例如0)替换。
在使用不同的缺失值策略时,需要注意以下几个问题:
02 异常值处理
有关异常值的确定有很多规则和方法,这里使用Z标准化得到的阈值作为判断标准:当标准化后的得分超过阈值则为异常。完整代码如下。
示例代码分为3个部分。
1. 导入本例需要的Pandas库
import pandas as pd # 导入Pandas库
2. 生成异常数据
df = pd.DataFrame({'col1': [1, 120, 3, 5, 2, 12, 13],
'col2': [12, 17, 31, 53, 22, 32, 43]})
print(df) # 打印输出
直接通过DataFrame创建一个7行2列的数据框,打印输出结果如下:
col1 col2
0 1 12
1 120 17
2 3 31
3 5 53
4 2 22
5 12 32
6 13 43
3. 为通过Z-score方法判断异常值
df_zscore = df.copy() # 复制一个用来存储Z-score得分的数据框
cols = df.columns # 获得数据框的列名
for col in cols: # 循环读取每列
df_col = df[col] # 得到每列的值
z_score = (df_col - df_col.mean()) / df_col.std() # 计算每列的Z-score得分
df_zscore[col] = z_score.abs() > 2.2 # 判断Z-score得分是否大于2.2,如果是则为True,否则为False
print(df_zscore) # 打印输出
本过程中,先通过 df.copy() 复制一个原始数据框的副本,用来存储Z-score标准化后的得分,再通过 df.columns 获得原始数据框的列名,接着通过循环判断每一列中的异常值。在判断逻辑中,对每一列的数据进行使用自定义的方法做Z-score值标准化得分计算,然后与阈值2.2做比较,如果大于阈值则为异常。本段代码返回结果如下:
col1 col2
0 False False
1 True False
2 False False
3 False False
4 False False
5 False False
6 False False
在本示例方法中,阈值的设定是确定异常与否的关键,通常当阈值大于2.2时,就是相对异常的表现值。
4. 删除带有异常值所在的记录行
df_drop_outlIEr = df[df_zscore['col1'] == False]
print(df_drop_outlIEr)
本段代码里我们直接使用了Pandas的选择功能,即只保留在 df_zscore 中异常列(col1)为 False 的列。完成后在输出的结果中可以看到,删除了 index 值为1的数据行。
col1 col2
0 1 12
2 3 31
3 5 53
4 2 22
5 12 32
6 13 43
上述过程中,主要需要考虑的关键点是:如何判断异常值。
对于有固定业务规则的可直接套用业务规则,而对于没有固定业务规则的,可以采用常见的数学模型进行判断:
异常值的定义带有较强的主观判断色彩,具体需要根据实际情况选择。
03 重复值处理
有关重复值的处理代码分为4个部分。
1. 导入用到的Pandas库
import pandas as pd # 导入Pandas库
2. 生成重复数据
data1, data2, data3, data4 = ['a', 3], ['b', 2], ['a', 3], ['c', 2]
df = pd.DataFrame([data1, data2, data3, data4], columns=['col1', 'col2'])
print(df)
在代码中,我们在一列中直接给4个对象赋值,也可以拆分为4行分别赋值。该数据是一个4行2列数据框,数据结果如下:
col1 col2
0 a 3
1 b 2
2 a 3
3 c 2
3. 判断重复数据
isDuplicated = df.duplicated() # 判断重复数据记录
print(isDuplicated) # 打印输出
判断数据记录是否为重复值,返回每条数据记录是否重复结果,取值为 True 或False。判断方法为 df.duplicated(),该方法中两个主要的参数是 subset 和keep。
结果如下:
0 False
1 False
2 True
3 False
dtype: bool
4. 删除重复值
print(df.drop_duplicates()) # 删除数据记录中所有列值相同的记录
print(df.drop_duplicates(['col1'])) # 删除数据记录中col1值相同的记录
print(df.drop_duplicates(['col2'])) # 删除数据记录中col2值相同的记录
print(df.drop_duplicates(['col1', 'col2'])) # 删除数据记录中指定列(col1/col2)值相同的记录
该 *** 作的核心方法是 df.drop_duplicates(),该方法的作用是基于指定的规则判断为重复值之后,删除重复值,其参数跟 df.duplicated() 完全相同。在该部分方法示例中,依次使用默认规则(全部列相同的数据记录)、col1列相同、col2列相同以及指定col1和col2完全相同4种规则进行去重。返回结果如下。
删除数据记录中所有列值相同的记录,index为2的记录行被删除:
col1 col2
0 a 3
1 b 2
3 c 2
删除数据记录中col1值相同的记录,index为2的记录行被删除:
col1 col2
0 a 3
1 b 2
3 c 2
删除数据记录中col2值相同的记录,index为2和3的记录行被删除:
col1 col2
0 a 3
1 b 2
删除数据记录中指定列(col1和col2)值相同的记录,index为2的记录行被删除:
col1 col2
0 a 3
1 b 2
3 c 2
提示:由于数据是通过随机数产生,因此读者 *** 作的结果可能与上述示例的数据结果不同。
除了可以使用Pandas来做重复值判断和处理外,也可以使用Numpy中的unique() 方法,该方法返回其参数数组中所有不同的值,并且按照从小到大的顺序排列。Python自带的内置函数 set 方法也能返回唯一元素的集合。
上述过程中,主要需要考虑的关键点是:如何对重复值进行处理。重复值的判断相对简单,而判断之后如何处理往往不是一个技术特征明显的工作,而是侧重于业务和建模需求的工作。
总结以上是内存溢出为你收集整理的Python代码实 *** :详解数据清洗全部内容,希望文章能够帮你解决Python代码实 *** :详解数据清洗所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)