Pandas缺失数据有哪些情况,分别如何是好
Admin 2022-08-11 群英技术资讯 281 次浏览
在pandas
中,缺失数据显示为NaN。缺失值有3种表示方法,np.nan
,none
,pd.NA
。
缺失值有个特点(坑),它不等于任何值,连自己都不相等。如果用nan
和任何其它值比较都会返回nan
。
np.nan == np.nan >> False
也正由于这个特点,在数据集读入以后,不论列是什么类型的数据,默认的缺失值全为np.nan
。
因为nan
在Numpy
中的类型是浮点,因此整型列会转为浮点;而字符型由于无法转化为浮点型,只能归并为object类型('O'),原来是浮点型的则类型不变。
type(np.nan) >> float
pd.Series([1,2,3]).dtype >> dtype('int64') pd.Series([1,np.nan,3]).dtype >> dtype('float64')
初学者做数据处理遇见object类型会发懵,不知道这是个啥,明明是字符型,导入后就变了,其实是因为缺失值导致的。
除此之外,还要介绍一种针对时间序列的缺失值,它是单独存在的,用NaT表示,是pandas
的内置类型,可以视为时间序列版的np.nan
,也是与自己不相等。
s_time = pd.Series([pd.Timestamp('20220101')]*3) s_time >> 0 2022-01-01 1 2022-01-01 2 2022-01-01 dtype:datetime64[ns] ----------------- s_time[2] = pd.NaT s_time >> 0 2022-01-01 1 2022-01-01 2 NaT dtype:datetime64[ns]
还有一种就是None
,它要比nan
好那么一点,因为它至少自己与自己相等。
None == None >> True
在传入数值类型后,会自动变为np.nan
。
type(pd.Series([1,None])[1]) >> numpy.float64
只有当传入object
类型时是不变的,因此可以认为如果不是人工命名为None
的话,它基本不会自动出现在pandas
中,所以None
大家基本也看不到。
type(pd.Series([1,None],dtype='O')[1]) >> NoneType
pandas1.0以后的版本中引入了一个专门表示缺失值的标量pd.NA,它代表空整数、空布尔值、空字符,这个功能目前处于实验阶段。
开发者也注意到了这点,对于不同数据类型采取不同的缺失值表示会很乱。pd.NA就是为了统一而存在的。pd.NA的目标是提供一个缺失值指示器,可以在各种数据类型中一致使用(而不是np.nan、None或者NaT分情况使用)。
s_new = pd.Series([1, 2], dtype="Int64") s_new >> 0 1 1 2 dtype: Int64 ----------------- s_new[1] = pd.NaT s_new >> 0 1 1 <NA> dtype: Int64
同理,对于布尔型、字符型一样不会改变原有数据类型,这样就解决了原来动不动就变成object
类型的麻烦了。
下面是pd.NA的一些常用算术运算和比较运算的示例:
##### 算术运算 # 加法 pd.NA + 1 >> <NA> ----------- # 乘法 "a" * pd.NA >> <NA> ----------- # 以下两种其中结果为1 pd.NA ** 0 >> 1 ----------- 1 ** pd.NA >> 1 ##### 比较运算 pd.NA == pd.NA >> <NA> ----------- pd.NA < 2.5 >> <NA> ----------- np.log(pd.NA) >> <NA> ----------- np.add(pd.NA, 1) >> <NA>
了解了缺失值的几种形式后,我们要知道如何判断缺失值。对于一个dataframe
而言,判断缺失的主要方法就是isnull()
或者isna()
,这两个方法会直接返回True
和False
的布尔值。可以是对整个dataframe
或者某个列。
df = pd.DataFrame({ 'A':['a1','a1','a2','a3'], 'B':['b1',None,'b2','b3'], 'C':[1,2,3,4], 'D':[5,None,9,10]}) # 将无穷设置为缺失值 pd.options.mode.use_inf_as_na = True
df.isnull() >> A B C D 0 False False False False 1 False True False True 2 False False False False 3 False False False False
df['C'].isnull() >> 0 False 1 False 2 False 3 False Name: C, dtype: bool
如果想取非缺失可以用notna()
,使用方法是一样的,结果相反。
一般我们会对一个dataframe
的列进行缺失统计,查看每个列有多少缺失,如果缺失率过高再进行删除或者插值等操作。那么直接在上面的isnull()
返回的结果上直接应用.sum()
即可,axis
默认等于0,0是列,1是行。
## 列缺失统计 isnull().sum(axis=0)
但是很多情况下,我们也需要对行进行缺失值判断。比如一行数据可能一个值都没有,如果这个样本进入模型,会造成很大的干扰。因此,行列两个缺失率通常都要查看并统计。
操作很简单,只需要在sum()
中设置axis=1
即可。
## 行缺失统计 isnull().sum(axis=1)
有时我不仅想要知道缺失的数量,我更想知道缺失的比例,即缺失率。正常可能会想到用上面求得数值再比上总行数。但其实这里有个小技巧可以一步就实现。
## 缺失率 df.isnull().sum(axis=0)/df.shape[0] ## 缺失率(一步到位) isnull().mean()
筛选需要loc配合完成,对于行和列的缺失筛选如下:
# 筛选有缺失值的行 df.loc[df.isnull().any(1)] >> A B C D 1 a1 None 2 NaN ----------------- # 筛选有缺失值的列 df.loc[:,df.isnull().any()] >> B D 0 b1 5.0 1 None NaN 2 b2 9.0 3 b3 10.0
如果要查询没有缺失值的行和列,可以对表达式用取反~
操作:
df.loc[~(df.isnull().any(1))] >> A B C D 0 a1 b1 1 5.0 2 a2 b2 3 9.0 3 a3 b3 4 10.0
上面使用了any
判断只要有缺失就进行筛选,也可以用all
判断是否全部缺失,同样可以对行里进行判断,如果整列或者整行都是缺失值,那么这个变量或者样本就失去了分析的意义,可以考虑删除。
一般我们对缺失值有两种处理方法,一种是直接删除,另外一种是保留并填充。下面先介绍填充的方法fillna
。
# 将dataframe所有缺失值填充为0 df.fillna(0) >> A B C D 0 a1 b1 1 5.0 1 a1 0 2 0.0 2 a2 b2 3 9.0 3 a3 b3 4 10.0 -------------- # 将D列缺失值填充为-999 df.D.fillna('-999') >> 0 5 1 -999 2 9 3 10 Name: D, dtype: object
方法很简单,但使用时需要注意一些参数。
fillna(0, inplace=True)
来让填充生效,原dataFrame被填充。methond
方法来实现向前或者向后填充,pad/ffill
为向前填充,bfill/backfill
为向后填充,比如df.fillna(methond='ffill')
,也可以简写为df.ffill()
。df.ffill() >> A B C D 0 a1 b1 1 5.0 1 a1 b1 2 5.0 2 a2 b2 3 9.0 3 a3 b3 4 10.0
原缺失值都会按照前一个值来填充(B列1行,D列1行)。
除了用前后值来填充,也可以用整个列的均值来填充,比如对D列的其它非缺失值的平均值8来填充缺失值。
df.D.fillna(df.D.mean()) >> 0 5.0 1 8.0 2 9.0 3 10.0 Name: D, dtype: float64
删除缺失值也非情况,比如是全删除还是删除比较高缺失率,这个要看自己的容忍程度,真实的数据必然会存在缺失的,这个无法避免。而且缺失在某些情况下也代表了一定的含义,要视情况而定。
# 全部直接删除 df.dropna() >> A B C D 0 a1 b1 1 5.0 2 a2 b2 3 9.0 3 a3 b3 4 10.0
# 行缺失删除 df.dropna(axis=0) >> A B C D 0 a1 b1 1 5.0 2 a2 b2 3 9.0 3 a3 b3 4 10.0
# 列缺失删除 df.dropna(axis=1) >> A C 0 a1 1 1 a1 2 2 a2 3 3 a3 4 ------------- # 删除指定列范围内的缺失,因为C列无缺失,所以最后没有变化 df.dropna(subset=['C']) >> A B C D 0 a1 b1 1 5.0 1 a1 None 2 NaN 2 a2 b2 3 9.0 3 a3 b3 4 10.0
这个可以考虑用筛选的方法来实现,比如要删除列缺失大于0.1的(即筛选小于0.1的)。
df.loc[:,df.isnull().mean(axis=0) < 0.1] >> A C 0 a1 1 1 a1 2 2 a2 3 3 a3 4 ------------- # 删除行缺失大于0.1的 df.loc[df.isnull().mean(axis=1) < 0.1] >> A B C D 0 a1 b1 1 5.0 2 a2 b2 3 9.0 3 a3 b3 4 10.0
如果不对缺失值处理,那么缺失值会按照什么逻辑进行计算呢?下面我们一起看一下各种运算下缺失值的参与逻辑。
df >>A B C D 0 a1 b1 1 5.0 1 a1 None 2 NaN 2 a2 b2 3 9.0 3 a3 b3 4 10.0 --------------- # 对所有列求和 df.sum() >> A a1a1a2a3 C 10 D 24
可以看到,加法是会忽略缺失值的。
# 对D列进行累加 df.D.cumsum() >> 0 5.0 1 NaN 2 14.0 3 24.0 Name: D, dtype: float64 --------------- df.D.cumsum(skipna=False) >> 0 5.0 1 NaN 2 NaN 3 NaN Name: D, dtype: float64
cumsum
累加会忽略NA,但值会保留在列中,可以使用skipna=False
跳过有缺失值的计算并返回缺失值。
# 对列计数 df.count() >> A 4 B 3 C 4 D 3 dtype: int64
缺失值不进入计数范围里。
df.groupby('B').sum() >> C D B b1 1 5.0 b2 3 9.0 b3 4 10.0 --------------- df.groupby('B',dropna=False).sum() >> C D B b1 1 5.0 b2 3 9.0 b3 4 10.0 NaN 2 0.0
聚合时会默认忽略缺失值,如果要缺失值计入到分组里,可以设置dropna=False
。这个用法和其它比如value_counts
是一样的,有的时候需要看缺失值的数量。以上就是所有关于缺失值的常用操作了,从理解缺失值的3种表现形式开始,到缺失值判断、统计、处理、计算等。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要介绍了分别利用PyQT5和Tkinter实现电脑的定时关机小程序,文中的示例代码讲解详细,对我们学习Python有一定的帮助,快跟随小编一起学习一下吧
Python内置函数-exec() 函数。exec 执行储存在字符串或文件中的 Python 语句,相比于 eval,exec可以执行更复杂的 Python 代码。
我们通常会遇到对数据库中的数据进行排序的问题,下面这篇文章主要给大家介绍了关于python中sort()和sorted()的区别及用法的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
List(列表)作为python中使用最频繁的数据类型,如果能够把列表掌握,那么对于Python的掌握是有很大帮助的。
api接口在我们开发中的重要性相信大家都这篇文章主要给大家介绍了关于利用python写api接口实战的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008