Pandas:缺失数据

Pandas:缺失数据

Pandas在步入1.0后,对数据类型也做出了新的尝试,尤其是Nullable类型和String类型,了解这些可能在未来成为主流的新特性是必要的

import pandas as pd
import numpy as np
df = pd.read_csv(‘data/table_missing.csv‘)
df.head()

一、缺失观测及其类型

1. 了解缺失信息

isna和notna方法

isna和notna方法

df[‘Physics‘].isna().head()
df[‘Physics‘].notna().head()
df.isna().head()
df.isna().sum()
df.info()

查看缺失值的所以在行

df[df[‘Physics‘].isna()]
df[df.notna().all(1)]

2. 三种缺失符号

np.nan

np.nan是一个麻烦的东西,首先它不等与任何东西,甚至不等于自己

np.nan == np.nan
    np.nan == 0
    np.nan == None
    # 在用equals函数比较时,自动略过两侧全是np.nan的单元格,因此结果不会影响
    df.equals(df)
    # 其次,它在numpy中的类型为浮点,由此导致数据集读入时,即使原来是整数的列,只要有缺失值就会变为浮点型
    type(np.nan)
    pd.Series([1,2,3]).dtype
    pd.Series([1,np.nan,3]).dtype
    # 此外,对于布尔类型的列表,如果是np.nan填充,那么它的值会自动变为True而不是False
    pd.Series([1,np.nan,3],dtype=‘bool‘)
    s = pd.Series([True,False],dtype=‘bool‘)
s[1]=np.nan
s

NaT

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

s_time = pd.Series([pd.Timestamp(‘20120101‘)]*5)
s_time
s_time[2] = None
s_time
s_time[2] = np.nan
s_times_time[2] = pd.NaT
s_time
type(s_time[2])
s_time[2] == s_time[2]
s_time.equals(s_time)
s = pd.Series([True,False],dtype=‘bool‘)
s[1]=pd.NaT
s

Nullable类型与NA符号

这是Pandas在1.0新版本中引入的重大改变,其目的就是为了(在若干版本后)解决之前出现的混乱局面,统一缺失值处理方法
"The goal of pd.NA is provide a “missing” indicator that can be used consistently across data types (instead of np.nan, None or pd.NaT depending on the data type)."——User Guide for Pandas v-1.0
官方鼓励用户使用新的数据类型和缺失类型pd.NA

# Nullable整形
# 对于该种类型而言,它与原来标记int上的# 符号区别在于首字母大写:‘Int‘
s_original = pd.Series([1, 2], dtype="int64")
s_original
s_new = pd.Series([1, 2], dtype="Int64")
s_new
s_original[1] = np.nan
s_original
s_new[1] = np.nan
s_new
s_new[1] = None
s_new
s_new[1] = pd.NaT
s_new

# Nullable布尔
# 对于该种类型而言,作用与上面的类似,记# 号为boolean
s_original = pd.Series([1, 0], dtype="bool")
s_original
s_new = pd.Series([0, 1], dtype="boolean")
s_new
s_original[0] = np.nan
s_original
s_original = pd.Series([1, 0], dtype="bool") #此处重新加一句是因为前面赋值改变了bool类型
s_original[0] = None
s_original
s_new[0] = np.nan
s_new
s_new[0] = None
s_new
s_new[0] = pd.NaT
s_new
s = pd.Series([‘dog‘,‘cat‘])
s[s_new]

# string类型
#该类型是1.0的一大创新,目的之一就是为了区分开原本含糊不清的object类型,这里将简要地提及string,因为它是第7章的主题内容
#它本质上也属于Nullable类型,因为并不会因为含有缺失而改变类型
s = pd.Series([‘dog‘,‘cat‘],dtype=‘string‘)
s
s[0] = np.nan
s
s[0] = None
s

NA

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

# 算术运算和比较运算
pd.NA ** 0
1 ** pd.NA

5. convert_dtypes方法

这个函数的功能往往就是在读取数据时,就把数据列转为Nullable类型,是1.0的新函数

pd.read_csv(‘data/table_missing.csv‘).dtypes
pd.read_csv(‘data/table_missing.csv‘).convert_dtypes().dtypes

二、缺失数据的运算与分组

1. 加号与乘号规则

使用加法时,缺失值为0

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

使用乘法时,缺失值为1

s.prod()

groupby方法中的缺失值

自动忽略为缺失值的组

df_g = pd.DataFrame({‘one‘:[‘A‘,‘B‘,‘C‘,‘D‘,np.nan],‘two‘:np.random.randn(5)})
df_g
df_g.groupby(‘one‘).groups

df_g.groupby(‘one‘).groups

fillna

df[‘Physics‘].fillna(‘missing‘).head()
df[‘Physics‘].fillna(method=‘ffill‘).head()
df[‘Physics‘].fillna(method=‘backfill‘).head()

dropna

df_d = pd.DataFrame({‘A‘:[np.nan,np.nan,np.nan],‘B‘:[np.nan,3,2],‘C‘:[3,2,1]})
df_d
df_d.dropna(axis=0)
df_d.dropna(axis=1)

四、插值(interpolation)

1. 线性插值

s = pd.Series([1,10,15,-5,-2,np.nan,np.nan,28])
s
s.interpolate()

s.index = np.sort(np.random.randint(50,300,8))
s.interpolate()
#值不变

2. 高级插值方法

此处的高级指的是与线性插值相比较,例如样条插值、多项式插值、阿基玛插值等(需要安装Scipy),方法详情请看这里
关于这部分仅给出一个官方的例子,因为插值方法是数值分析的内容,而不是Pandas中的基本知识:

ser = pd.Series(np.arange(1, 10.1, .25) ** 2 + np.random.randn(37))
missing = np.array([4, 13, 14, 15, 16, 17, 18, 20, 29])
ser[missing] = np.nan
methods = [‘linear‘, ‘quadratic‘, ‘cubic‘]
df = pd.DataFrame({m: ser.interpolate(method=m) for m in methods})
df.plot()

3. interpolate中的限制参数

s = pd.Series([1,np.nan,np.nan,np.nan,5])
s.interpolate(limit=2)
s = pd.Series([np.nan,np.nan,1,np.nan,np.nan,np.nan,5,np.nan,np.nan,])
s.interpolate(limit_direction=‘backward‘)
s = pd.Series([np.nan,np.nan,1,np.nan,np.nan,np.nan,5,np.nan,np.nan,])
s.interpolate(limit_area=‘inside‘)
s = pd.Series([np.nan,np.nan,1,np.nan,np.nan,np.nan,5,np.nan,np.nan,])
s.interpolate(limit_area=‘outside‘)

相关推荐