pandas学习-第六章

缺失数据

import pandas as pd 
import numpy as np
data=pd.read_csv(r'D:\jupyter Notebook\天池比赛\pandas学习\joyful-pandas-master\data\table_missing.csv')
data.head()
SchoolClassIDGenderAddressHeightWeightMathPhysics
0S_1C_1NaNMstreet_1173NaN34.0A+
1S_1C_1NaNFstreet_2192NaN32.5B+
2S_1C_11103.0Mstreet_2186NaN87.2B+
3S_1NaNNaNFstreet_216781.080.4NaN
4S_1C_11105.0NaNstreet_415964.084.8A-

缺失观测及其类型

了解缺失信息

  1. isna和notna方法
data['Physics'].isna().head()
0    False
1    False
2    False
3     True
4    False
Name: Physics, dtype: bool
data['Physics'].notna().head()
0     True
1     True
2     True
3    False
4     True
Name: Physics, dtype: bool
  • 对表格使用会返回整体的布尔值
data.isna().head()
SchoolClassIDGenderAddressHeightWeightMathPhysics
0FalseFalseTrueFalseFalseFalseTrueFalseFalse
1FalseFalseTrueFalseFalseFalseTrueFalseFalse
2FalseFalseFalseFalseFalseFalseTrueFalseFalse
3FalseTrueTrueFalseFalseFalseFalseFalseTrue
4FalseFalseFalseTrueFalseFalseFalseFalseFalse
  • 对表格空值进行汇总
data.isna().sum()
School      0
Class       4
ID          6
Gender      7
Address     0
Height      0
Weight     13
Math        5
Physics     4
dtype: int64
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 35 entries, 0 to 34
Data columns (total 9 columns):
 #   Column   Non-Null Count  Dtype  
---  ------   --------------  -----  
 0   School   35 non-null     object 
 1   Class    31 non-null     object 
 2   ID       29 non-null     float64
 3   Gender   28 non-null     object 
 4   Address  35 non-null     object 
 5   Height   35 non-null     int64  
 6   Weight   22 non-null     float64
 7   Math     30 non-null     float64
 8   Physics  31 non-null     object 
dtypes: float64(3), int64(1), object(5)
memory usage: 2.6+ KB
  • 个人比较倾向是用info语句,这样不仅仅可以看出缺失值还可以获得数据类型

  • isna和isnull的关系

pd.isna==pd.isna
True
  • 从以上我们可以看出isna就是isnull
  1. 查看缺失值的
data[data['Physics'].isna()]
SchoolClassIDGenderAddressHeightWeightMathPhysics
3S_1NaNNaNFstreet_216781.080.4NaN
8S_1C_21204.0Fstreet_516263.033.8NaN
13S_1C_31304.0NaNstreet_219570.085.2NaN
22S_2C_22203.0Mstreet_415591.073.8NaN
  1. 挑出所有非缺失值的列
  • 使用all就是全部非缺失值,如果是any就是至少有一个不是缺失值
data[data.notna().all(1)]
SchoolClassIDGenderAddressHeightWeightMathPhysics
5S_1C_21201.0Mstreet_515968.097.0A-
6S_1C_21202.0Fstreet_417694.063.5B-
12S_1C_31303.0Mstreet_718882.049.7B
17S_2C_12103.0Mstreet_415761.052.5B-
21S_2C_22202.0Fstreet_719477.068.5B+
25S_2C_32301.0Fstreet_415778.072.3B+
27S_2C_32303.0Fstreet_719099.065.9C
28S_2C_32304.0Fstreet_616481.095.5A-
29S_2C_32305.0Mstreet_418773.048.9B

三种缺失符号

np.nan

None

NaT

  • NaT是针对时间序列的缺失值,是Pandas的内置类型,可以完全看做时序版本的np.nan,与自己不等,且使用equals是也会被跳过

Nullable类型与NA符号

Nullable整形

  • 对于该种类型而言,它与原来标记int上的符号区别在于首字母大写:‘Int’
s_original=pd.Series([1,2],dtype='int64')
s_original
0    1
1    2
dtype: int64
s_new=pd.Series([1,2],dtype='Int64')
s_new
0    1
1    2
dtype: Int64
  • 它的好处就在于,其中前面提到的三种缺失值都会被替换为统一的NA符号,且不改变数据类型
s_original[1]=np.nan
s_original
0    1.0
1    NaN
dtype: float64
s_new[1]=np.nan
s_new
0       1
1    <NA>
dtype: Int64

Nullable布尔

  • 对于该种类型而言,作用与上面的类似,记号为boolean
s_original=pd.Series([1,0],dtype='bool')
s_original
0     True
1    False
dtype: bool
s_new=pd.Series([1,0],dtype='boolean')
s_new
0     True
1    False
dtype: boolean
s_original[0] = np.nan
s_original
0    NaN
1    0.0
dtype: float64
s_original[0] = None
s_original
0    False
1    False
dtype: bool
s_new[0] = np.nan
s_new
0     <NA>
1    False
dtype: boolean

string类型

  • 该类型是1.0的一大创新,目的之一就是为了区分开原本含糊不清的object类型,这里将简要地提及string,因为它是第7章的主题内容
  • 它本质上也属于Nullable类型,因为并不会因为含有缺失而改变类型
s=pd.Series(['dog','cat'],dtype='string')
s
0    dog
1    cat
dtype: string
s[0]=np.nan
s
0    <NA>
1     cat
dtype: string
s[0]=None
s
0    <NA>
1     cat
dtype: string
  • 此外,和object类型的一点重要区别就在于,在调用字符方法后,string类型返回的是Nullable类型,object则会根据缺失类型和数据类型而改变m
s1=pd.Series(['a',None,'b'],dtype='string')
s1.str.count('a')
0       1
1    <NA>
2       0
dtype: Int64
s2=pd.Series(['a',None,'b'],dtype='object')
s2.str.count('a')
0    1.0
1    NaN
2    0.0
dtype: float64
s1.str.isdigit()
0    False
1     <NA>
2    False
dtype: boolean
s2.str.isdigit()
0    False
1     None
2    False
dtype: object

NA的特性

逻辑运算

  • 只需看该逻辑运算的结果是否依赖pd.NA的取值,如果依赖,则结果还是NA,如果不依赖,则直接计算结果
True|pd.NA
True
False|pd.NA
<NA>
1|100
101
False &pd.NA
False
True & pd.NA
<NA>

算数运算符

  • 只有两种情况以外,其余都是NA
pd.NA**0
1
1**pd.NA
1

convert_dtypes方法

  • 这个函数的功能往往就是在读取数据时,就把数据列转为Nullable类型
data.dtypes
School      object
Class       object
ID         float64
Gender      object
Address     object
Height       int64
Weight     float64
Math       float64
Physics     object
dtype: object
data.convert_dtypes().dtypes
School      string
Class       string
ID           Int64
Gender      string
Address     string
Height       Int64
Weight       Int64
Math       float64
Physics     string
dtype: object

缺失数据的运算与分组

加号与乘号规则

使用加法时,缺失值为0

s=pd.Series([2,3,np.nan,4])
s.sum()
9.0

使用乘法时,缺失值为1

s.prod()
24.0

使用累计函数时,缺失值自动略过

s.cumsum()
0    2.0
1    5.0
2    NaN
3    9.0
dtype: float64
s.cummax()
0    2.0
1    3.0
2    NaN
3    4.0
dtype: float64
s.pct_change#计算变化率:(后一个值-前一个值)/前一个值
<bound method NDFrame.pct_change of 0    2.0
1    3.0
2    NaN
3    4.0
dtype: float64>

groupby方法中的缺失值

自动忽略为缺失值的组

df_g=pd.DataFrame({'one':['A','B','C','D',np.nan],'two':np.random.randn(5)})
df_g
onetwo
0A-1.123148
1B-0.610931
2C1.662203
3D-0.790061
4NaN-0.616937
df_g.groupby('one').groups
{'A': Int64Index([0], dtype='int64'),
 'B': Int64Index([1], dtype='int64'),
 'C': Int64Index([2], dtype='int64'),
 'D': Int64Index([3], dtype='int64')}

填充与剔除

fillna方法

值填充与前后向填充(分别与ffill方法和bfill方法等价)

data['Physics'].fillna('missing').head()
0         A+
1         B+
2         B+
3    missing
4         A-
Name: Physics, dtype: object
data['Physics'].fillna(method='ffill').head()
0    A+
1    B+
2    B+
3    B+
4    A-
Name: Physics, dtype: object
  • 和之前相同

填充中的对齐特性

data_f=pd.DataFrame({'A':[1,3,np.nan],'B':[2,4,np.nan],'c':[3,5,np.nan]})
data_f.fillna(data_f.mean())
ABc
01.02.03.0
13.04.05.0
22.03.04.0

返回的结果中没有C,根据对齐特点不会被填充

data_f.fillna(data_f.mean()[['A','B']])
ABc
01.02.03.0
13.04.05.0
22.03.0NaN
data_f.fillna(data_f[['A','B']].mean())
ABc
01.02.03.0
13.04.05.0
22.03.0NaN
data_f.fillna(data_f.mean()[['A','B']])
ABc
01.02.03.0
13.04.05.0
22.03.0NaN

dropna方法

axis参数

df_d=pd.DataFrame({'A':[np.nan,np.nan,np.nan],'B':[np.nan,3,2],'C':[3,2,1]})
df_d
ABC
0NaNNaN3
1NaN3.02
2NaN2.01
df_d.dropna(axis=0)#删除有缺失值的行
ABC
df_d.dropna(axis=1)
C
03
12
21

how参数(可以选all或者any,表示全为缺失去除和存在缺失去除

subset参数(即在某一组列范围中搜索缺失值)

  • 这一部分与之前一样,不需要赘述

插值

线性插值

索引状态无关

  • 默认状态下,interpolate会对缺失的值进行线性插值
s=pd.Series([1,10,15,-5,-2,np.nan,np.nan,28])
s
0     1.0
1    10.0
2    15.0
3    -5.0
4    -2.0
5     NaN
6     NaN
7    28.0
dtype: float64
s.interpolate()
0     1.0
1    10.0
2    15.0
3    -5.0
4    -2.0
5     8.0
6    18.0
7    28.0
dtype: float64
s.interpolate().plot()
<matplotlib.axes._subplots.AxesSubplot at 0x261a0e64988>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZtanDBUv-1592834890647)(output_100_1.png)]

s.index=np.sort(np.random.randint(50,300,8))
s.interpolate()
75      1.0
108    10.0
130    15.0
133    -5.0
145    -2.0
155     8.0
194    18.0
208    28.0
dtype: float64
s.interpolate().plot()
<matplotlib.axes._subplots.AxesSubplot at 0x261a3a46f08>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cNORfHpv-1592834890650)(output_102_1.png)]

  • 可以看出此时的插值与索引无关,获得的插值不变

与索引有关的插值

  • method中的index和time选项可以使插值线性地依赖索引,即插值为索引的线性函数
s.interpolate(method='index').plot()
<matplotlib.axes._subplots.AxesSubplot at 0x261a3740688>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pxHCParN-1592834890651)(output_105_1.png)]

问题与练习

问题

如何删除缺失值占比超过25%的列?

#通过给定的数据集进行说明
data.info()#得到data一共35个值
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 35 entries, 0 to 34
Data columns (total 9 columns):
 #   Column   Non-Null Count  Dtype  
---  ------   --------------  -----  
 0   School   35 non-null     object 
 1   Class    31 non-null     object 
 2   ID       29 non-null     float64
 3   Gender   28 non-null     object 
 4   Address  35 non-null     object 
 5   Height   35 non-null     int64  
 6   Weight   22 non-null     float64
 7   Math     30 non-null     float64
 8   Physics  31 non-null     object 
dtypes: float64(3), int64(1), object(5)
memory usage: 2.6+ KB
data.isna().sum()/35#得到weight 缺失值超过25%
#这里不能使用data.count(),缺失值会跳过!
School     0.000000
Class      0.114286
ID         0.171429
Gender     0.200000
Address    0.000000
Height     0.000000
Weight     0.371429
Math       0.142857
Physics    0.114286
dtype: float64
data.drop(data[['Gender','Weight']],axis=1)
SchoolClassIDAddressHeightMathPhysics
0S_1C_1NaNstreet_117334.0A+
1S_1C_1NaNstreet_219232.5B+
2S_1C_11103.0street_218687.2B+
3S_1NaNNaNstreet_216780.4NaN
4S_1C_11105.0street_415984.8A-
5S_1C_21201.0street_515997.0A-
6S_1C_21202.0street_417663.5B-
7S_1C_2NaNstreet_616058.8A+
8S_1C_21204.0street_516233.8NaN
9S_1C_21205.0street_616768.4B-
10S_1C_31301.0street_4161NaNB+
11S_1NaN1302.0street_117587.7A-
12S_1C_31303.0street_718849.7B
13S_1C_31304.0street_219585.2NaN
14S_1C_3NaNstreet_518761.7B-
15S_2C_12101.0street_7159NaNC
16S_2C_12102.0street_616150.6B+
17S_2C_12103.0street_415752.5B-
18S_2NaN2104.0street_515972.2B+
19S_2C_12105.0street_417034.2A
20S_2C_22201.0street_5193NaNB
21S_2C_22202.0street_719468.5B+
22S_2C_22203.0street_415573.8NaN
23S_2C_2NaNstreet_117547.2B-
24S_2C_22205.0street_7159NaNB
25S_2C_32301.0street_415772.3B+
26S_2NaN2302.0street_5171NaNA
27S_2C_32303.0street_719065.9C
28S_2C_32304.0street_616495.5A-
29S_2C_32305.0street_418748.9B
30S_2C_42401.0street_215945.3A
31S_2C_42402.0street_716648.7B
32S_2C_42403.0street_615859.7B+
33S_2C_42404.0street_216067.7B
34S_2C_42405.0street_619347.6B
#方法二,计算出超过25%的缺失值个数
35*0.75
#即超过8个的去除
26.25
data.isna().sum()#选择weight去除
School      0
Class       4
ID          6
Gender      7
Address     0
Height      0
Weight     13
Math        5
Physics     4
dtype: int64

什么是Nullable类型?请谈谈为什么要引入这个设计?

它是一种特殊的整形

  1. 解决之前因为缺失值而导致的数据类型改变
  2. 同一不同类型的缺失值的符号

对于一份有缺失值的数据,可以采取哪些策略或方法深化对它的了解

  1. 判断缺失值数量及特征重要性再选择策略
  2. 对于不是特别重要的特征且缺失数据量较大,考虑删除特征,dropna或者drop
  3. 对于重要特征,那么考虑进行插值,除了本文所说的插值,也可以考虑使用决策树等机器学习方法进行填补

练习

现有一份虚拟数据集,列类型分别为string/浮点/整型,请解决如下问题:

  1. 请以列类型读入数据,并选出C为缺失值的行。
data_1=pd.read_csv(r'D:\jupyter Notebook\天池比赛\pandas学习\joyful-pandas-master\data\Missing_data_one.csv')
data_1.convert_dtypes()
ABC
0not_NaN0.9224
1not_NaN0.700<NA>
2not_NaN0.5038
3not_NaN0.9384
4not_NaN0.95210
5not_NaN0.972<NA>
6not_NaN0.5722
7not_NaN0.52310
8not_NaN0.55710
9not_NaN0.6954
10not_NaN0.7821
11not_NaN0.736<NA>
12not_NaN0.7060
13not_NaN0.6823
14not_NaN0.9168
15not_NaN0.9355
16not_NaN0.8231
17not_NaN0.7632
18not_NaN0.9765
19not_NaN0.684<NA>
20not_NaN0.9352
21not_NaN0.913<NA>
22not_NaN0.5385
23not_NaN0.5522
24not_NaN0.8925
25not_NaN0.8917
26not_NaN0.9602
27not_NaN0.7996
28not_NaN0.5770
29not_NaN0.8014
data_1.dtypes
A     object
B    float64
C    float64
dtype: object
data_1[data_1['C'].isna()]
#
ABC
1not_NaN0.700NaN
5not_NaN0.972NaN
11not_NaN0.736NaN
19not_NaN0.684NaN
21not_NaN0.913NaN
  1. 现需要将A中的部分单元转为缺失值,单元格中的最小转换概率为25%,且概率大小与所在行B列单元的值成正比。
total_b=data_1['B'].sum()
total_b
23.194999999999997
min_b=data_1['B'].min()
data_1['A']=pd.Series(list(zip(data_1['A'].values,
                              data_1['B'].values))).apply(lambda x:x[0] 
                                                         if np.random.rand()>0.25*x[1]/min_b
                                                         else np.nan)
data_1.head()
ABC
0NaN0.9224.0
1NaN0.700NaN
2not_NaN0.5038.0
3NaN0.9384.0
4NaN0.95210.0

现有一份缺失的数据集,记录了36个人来自的地区、身高、体重、年龄和工资,请解决如下问题

  1. 统计各列缺失的比例并选出在后三列中至少有两个非缺失值的行。
data_2=pd.read_csv(r'D:\jupyter Notebook\天池比赛\pandas学习\joyful-pandas-master\data\Missing_data_two.csv')
data_2.head()
编号地区身高体重年龄工资
01A157.50NaN47.015905.0
12B202.0091.8025.0NaN
23C169.0962.18NaNNaN
34A166.6159.9577.05434.0
45B185.19NaN62.04242.0
data_2.info() #一共36个值
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 36 entries, 0 to 35
Data columns (total 6 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   编号      36 non-null     int64  
 1   地区      36 non-null     object 
 2   身高      36 non-null     float64
 3   体重      28 non-null     float64
 4   年龄      27 non-null     float64
 5   工资      28 non-null     float64
dtypes: float64(4), int64(1), object(1)
memory usage: 1.8+ KB
data_2.isna().sum()/36
#参考答案用的shape[0],之前学习的也是可以使用列索引或者len进行,这两个方法更好
编号    0.000000
地区    0.000000
身高    0.000000
体重    0.222222
年龄    0.250000
工资    0.222222
dtype: float64
data_2[data_2.iloc[:,3:].isna().sum(1)<=1]
编号地区身高体重年龄工资
01A157.50NaN47.015905.0
12B202.0091.8025.0NaN
34A166.6159.9577.05434.0
45B185.19NaN62.04242.0
56A187.1378.4255.013959.0
67C163.8157.4343.06533.0
78A183.8075.4248.019779.0
89B179.6771.7065.08608.0
910C186.0877.4765.012433.0
1011B163.4157.07NaN6495.0
1314B175.9968.39NaN13130.0
1516A165.68NaN46.013683.0
1617B166.4859.8331.017673.0
1718C191.6282.46NaN12447.0
1819A172.8365.5523.013768.0
1920B156.9951.2962.03054.0
2021C200.2290.2041.0NaN
2122A154.6349.1735.014559.0
2223B157.8752.0867.07398.0
2324A165.55NaN66.019890.0
2425C181.7873.6063.011383.0
2526A164.4357.9934.019899.0
2728C172.3965.1543.010362.0
2829B162.1255.91NaN13362.0
2930A183.7375.3658.08270.0
3031C181.19NaN41.012616.0
3132B167.2860.5564.018317.0
3435B170.1263.1177.07398.0
3536C180.4772.4278.09554.0
  1. 请结合身高列和地区列中的数据,对体重进行合理插值。
data_21=data_2.copy()
data_missing=data_21[data_21['体重'].isna()]
data_missing.groupby('地区').head()
编号地区身高体重年龄工资
01A157.50NaN47.015905.0
45B185.19NaN62.04242.0
1213C177.37NaN79.0NaN
1516A165.68NaN46.013683.0
2324A165.55NaN66.019890.0
2627B158.28NaN51.0NaN
3031C181.19NaN41.012616.0
3233C181.01NaNNaN13021.0

总结

这是pandas学习第六章课程,总结如下:

  1. 本次学习的知识点很多在上一轮学习中已经有了,所以学习起来的压力并不大
  2. 主要的问题还是在综合练习的过程中,只能完成部分习题,还是编程思想的问题。这个也是贯穿在自己的数据处理过程中。
  3. 不要怕麻烦,不要想着一行代码解决很多问题。自己可以小步迭代,进行多次步骤,完成需要的效果。
  4. 本次学习与上一轮复习同步进行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值