缺失值的处理

数据缺失。这也是大部分数据分析工作所会遇到的之一。而正确处理缺失值,也是我们在数据分析中数据预处理环节的关键的一环。下面我将讲讲在我学习Pandas的时候,对缺失值处理的一些总结:

表现形式是 : NaN NAN nan 都是缺失值

处理丢失数据

  • 怎么去创建缺失值:(缺失值是怎么来的 )
    • None
    • np.nan
1
2
3
4
5
6
7
8
9
10
11
12
13
# NaN值的表现   None np.nan 
import pandas as pd
import numpy as np

df = pd.DataFrame(data=np.random.randint(0,100,size=(7,5)), index =[i for i in 'pythonl'])
df.iloc[2,3] = None
df.iloc[4,2] = np.nan
df.iloc[1,4] = None


# nan值是否可以运算 ?
np.nan + 1 # 可以进行运算

pandas处理缺失值操作

  • 方式1:查看空值
    • isnull,any
    • notnull,all
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 检测整张表中的缺失值的数据  
df.isnull() # 返回Dataframe的形式 TRUE是缺失和False 是不缺失,series也有这个方法

#r如果哪些行中有空值
df.isnull().any(axis=1) # 此时注意和drop的区别 # 不写默认是列
#r如果哪些列中有空值
df.isnull().any(axis=0)


df.notnull() # True 是不缺失 ,False 是缺失
#r如果哪些行中有空值
df.notnull().all(axis=1)
#r如果哪些列中有空值
df.notnull().all(axis=0)


# 布尔值作为索引 的时候 只能是代表的是行 所以说 axis= 1 此时会把所有的非缺失值取出
df[df.notnull().all(axis=1)]



# 删除为NaN 值的数据
#获取对应的空的Dataframe数据
df[df.isnull().any(axis = 1)]
# 取出索引
df[df.isnull().any(axis = 1)].index
# 根据drop函数进行删除
df.drop(labels=indexs,axis=0) # 此时在drop中 axis = 0 为行数据


方式2:

  • dropna:可以直接将缺失的行或者列进行删除

删除缺失值

dropna()

函数作用:删除含有空值的行或列

axis

:维度,axis=0表示index行,axis=1表示columns列,默认为0

how:

"all"表示这一行或列中的元素全部缺失(为nan)才删除这一行或列,"any"表示这一行或列中只要有元素缺失,就删除这一行或列

thresh

保留至少3个非nan值的行或者列 注意是保留

inplace

刷选过缺失值得新数据是存为副本还是直接在原数据上进行修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

df = pd.DataFrame([[np.nan, 2, np.nan, 0],
[3, 4, "", 1],
[np.nan, np.nan, np.nan, 5],
[np.nan, 3, "", 4]],
columns=list('ABCD'))

df.dropna(how='any',axis=1) # 带有nan的列就删除 默认是 any
df.dropna(axis=1) # 表示删除了带nan的列
df.dropna() # 默认是 axis= 0 是行



df = pd.DataFrame([[np.nan, 2, np.nan, 0],
[3, 4, "", 1],
[np.nan, np.nan, np.nan, None],
[np.nan, 3, "", 4]],
columns=list('ABCD'))

df.dropna(how='all',axis=0) # how= 'all' 的时候 是列或者行全为空的时候才删除


df = pd.DataFrame([[np.nan, 2, np.nan, 0],
[3, 4, np.nan, 1],
[np.nan, np.nan, np.nan, 5],
[np.nan, 3, np.nan, 4]],
columns=list('ABCD'))
df
A B C D
0 NaN 2.0 NaN 0
1 3.0 4.0 NaN 1
2 NaN NaN NaN 5
3 NaN 3.0 NaN 4

>>>df.dropna(thresh=3) # 这参数用得很少 保留至少3个非nan值的行或者列 注意是保留

A B C D
1 3.0 4.0 NaN 1

填充缺失值

fillna()

参数:

value

需要用什么值去填充缺失值

axis参数

一般和method参数连用 axis= 1 代表是行 axis= 0 代表的是 列

inplace

参数的取值:True、False

True:直接修改原对象

False:原对象不变(缺省默认)

method

注意这个参数不能与value同时出现

method参数的取值 : {‘pad’, ‘ffill’,‘backfill’, ‘bfill’, None}

pad/ffill:用前一个非缺失值去填充该缺失值

backfill/bfill:用下一个非缺失值填充该缺失值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
df = pd.DataFrame([[np.nan, 2, np.nan, 0],
[3, 4, "", 1],
[np.nan, np.nan, np.nan, 5],
[np.nan, 3, "", 4]],
columns=list('ABCD'))

df.fillna(3) # 进行值的填充 ,没对原对象进行修改
df.fillna(0,inplace=True)# 对nan值填充为0 ,并且对df进行改变 默认是False不改变
# 进行特定的行填充(赋值)
df.iloc[0] = df.iloc[0].fillna(9)

# 进行特定的列填充(赋值) 操作是把C列的nan值替换成 D列的平均值
df['C'] = df['C'].fillna(df['D'].mean())


# method参数
df = pd.DataFrame([[1 ,2, np.nan, 0],
[3, 4, "", 1],
[np.nan, 4, np.nan, 5],
[np.nan, 3, "", 4]],
columns=list('ABCD'))

df.fillna(axis=1,method='ffill') # 在 平行向(行)进行填充 找前一个变量填充 axis = 1 为行数据
df.fillna(axis=1,method='bfill') #



# 替换空值''
# 错误示范
df[df['C']==""]['C'] = 'hello'

# 找到索引
n_index = df[df['C'] == ""].index
df.loc[n_index,'C'] = 'hello' # 根据索引进行赋值


# 另外一种填充NaN值的方法
df.fillna({'A':0.3,'B':44,'C':55}) # 把A列的nan值都变成了 0.3 B列变成了44 ,c列变成了 55

缺失值的计算

1
2
3
4
5

df['A'].mean() # 不会计算缺失值
df['A'].sum()# 不会计算缺失值

df.loc[0,'A'] + 1 # 缺失值加任何数都是缺失值

替代值

replace
一对一替换

将数据表中的值“背包”全部替换为“挎包”。replace()函数括号中逗号前面的参数是需要替换的值,逗号后面的参数是替换后的值。
参数inplace默认是不对原表替换,设置为True则原表上替换。

1
2

data.replace('背包','挎包', inplace=True) # 对原对象进行修改
多对一
1
data.replace(['背包','手提包','单肩包','钱包'], '挎包')
多对多替换
1
data.replace({'背包':'大大大包', 16:3900, 58:6800},)

删除重复值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
data1,data2,data3,data4,data5 =['a',3,3],['b',2,3],['a',3,3],['c',2,3],['b',2,7]
df=pd.DataFrame([data1,data2,data3,data4,data5],columns=['col1','col2','col3'])


# 判断重复数据记录
isDu=df.duplicated() #判断重复数据记录 行与行之间的的进行对比比较



df.drop_duplicates() # 删除的是 为True的那一行的数据
df.drop_duplicates('col1')#删除col1列值相同记录行数据,index为2,4的记录行被删除

df.drop_duplicates('col2') #删除col2列值相同的记录,index为2和3的记录行被删除, 以index为最开始为基准

df.drop_duplicates(['col1','col2']) #删除指定列(col1和col2)值相同的记录 0 13
#特别注意 : 指定列的时候要加一个容器 列表 元组 也有inplace = True


""""
可以利用drop_duplicates()函数的参数keep来自定义删除重复值时保留哪个重复值所在的行。
例如:

参数keep默认设置为'first',表示保留第一个重复值所在的行。

"""

# 默认保留第一个重复值所在的行,删除其他重复值所在的行。

df.drop_duplicates('col1',keep = 'last') # 如果要保留最后一个重复值所在的行,从后往前依次进行对比,则将参数keep设置为'last'。

df.drop_duplicates(keep = False) # 还可以将参数keep设置为False,表示把重复值一个不留地全部删除。

获取唯一值

1
2
3
4
df['col1'].unique()

df['col1'].nunique() # 返回的是唯一值的个数

排序数据

排序数据主要会用到sort_values()函数

  • sort_values()函数的功能是将数据按照大小进行升序排序或降序排序;

sort_values()

sort_values()函数的常用参数有两个:

  • 一个是by,用于指定要排序的列;
  • 另一个是ascending,用于指定排序方式是升序还是降序。
1
2
data.sort_values(by='数量')  #  默认是升序 
data.sort_values(by='数量',ascending= False) #,ascending= False 为降序 如果数据相同按照索引排序

sort_index()

1
2
data.sort_index()
data.sort_index(ascending= False)

数据类型的转换

当利用pandas进行数据处理的时候,经常会遇到数据类型的问题,当拿到数据的时候,首先需要确定拿到的是正确类型的数据,一般通过数据类型的转化

转换数据类型 astype

1
2
3
4
5
6
7
8
9
10
11
df = pd.DataFrame({
'a': [1, 2, 3],
'b': [0.55, 0.66, 1.55],
'c': ['Jack', 'Tony', 'Posi']
})
df.dtypes # 查看数据类型
df.info()

df['b'].astype(int) # 把float类型转化成 int类型 向下取整
df['b'] = df['b'].astype('int') # 把转化完了以后进行对列的赋值 要不然没有修改

to_numeric()

把变量转化为数值类型(int,float)

1
2
3
4
5
6
7
8
9
10
11
12
df = pd.DataFrame({
'a': [1, 2, 3,7],
'b': [0.55, 0.66, 1.55,'miss'],
'c': ['Jack', 'Tony', 'Posi','James']
})

df['b'].astype('float') # 直接报错

df['b'] = pd.to_numeric(df['b'],errors='coerce') # 在非数值的时候添加NaN值
df['b'].dtype # 变成了 float 类型

df['b'] = df['b'].fillna(0) # 填充NaN值 进行赋值

时间类型的操作

to_datetime

可以使用to_datetime()函数把一个对象转化成datetime类型

该函数的作用是:将字符串输入转化为日期时间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#  to_datetime    set_index   to_period  resample 

data=pd.read_csv('data/1.data清洗/hz_weather.csv')
data.head()

data.info() # 可以看到日期是 字符串类型

# 1.修改日期格式
data['日期'] = pd.to_datetime(data ['日期'])

data.info()

# 2、将日期设置为索引
data.set_index('日期',inplace=True)


data.index

data.index<'2017-3-1'
# 或者
from datetime import datetime

data.index<datetime(2017,3,20)

# 提取1月份的数据

data[data.index.month ==1]


# 转换成月份
data.to_period('M') # Y D