python数据分析——缺失数据

参考资料:活用pandas库

        缺失数据有多种表示形式。在数据库中,缺失数据表示为NULL;在某些变成语言中使用NA表示。根据数据的来源,缺失值可能是空字符串("")或数据(比如88或99)。在pandas中使用NaN表示缺失值。

1、何为NaN值

        pandas中的NaN值来自numpy库。在numpy中,缺失值有集中表示形式:NaN、NAN或nan,但它们都是等同的。

        缺失值和其他类型的数据不同,实际上他们无甚意义。数据缺失了,也就无所谓等于或不等于。NaN也不等同于0或者空字符串。当然一个缺失值和另一个缺失值也是不相等的,pandas提供了isnull和notnull方法,用于判断某个值是否为缺失值

# 从numpy库导入缺失值
from numpy import NaN,NAN,nan
print(NaN==True)
print('-'*20)
print(NaN==False)
print('-'*20)
print(NaN==0)
print('-'*20)
print(NaN==1)

# 检测缺失值和缺失值是否相等
print(NaN==NaN)
print('-'*20)
print(NaN==nan)
print('-'*20)
print(NaN==NAN)
print('-'*20)
print(nan==NAN)

# isnull方法和notnull方法应用
import pandas as pd
print(pd.isnull(NAN))
print('-'*20)
print(pd.isnull(NaN))
print('-'*20)
print(pd.isnull(nan))
print('-'*20)
print(pd.notnull(NaN))
print('-'*20)
print(pd.notnull(42))
print('-'*20)
print(pd.notnull('string'))

2、缺失值的来源

        缺失值的两个来源:一是缺失值的数据集,二是数据整理过程。

(1)加载数据

        加载数据时,pandas会自动查找缺失数据单元,并在DataFrame中对该单元给出一个NaN值。在read_csv函数中,有3个参数与缺失值的读取有关:na_values、keep_default_na和na_filter。

        na_values参数允许指定额外的缺失值或NaN值。通常采用默认即可,但有些数据集可能会把99指定为缺失值,此时需要设置na_values=[99]来指定缺失值。

        keep_default_na参数是布尔值,它允许指定是否要把其他任何值视为缺失值。通常采用默认值True,即使用na_values参数额外指定的缺失值都会追加到缺失值列表中。若把keep_default_na设置为False,将只使用na_values中指定的缺失值。

        na_filter参数也是布尔型,用于指定某些值是否会被解读成“缺失值”。默认为True,即缺失值会被编码为NaN。如果设置为False,则不会将任何事重新编码为“缺失值”。

# 指定文件路径
visited_file=r"...\data\survey_visited.csv"

# 使用默认值加载数据
pd.read_csv(visited_file)

(2)合并数据

        当进行数据合并的时候,有时因两个表中的内容差异,而产生缺失值。

visited=pd.read_csv(r"C:\王池池\学习\python\活用pandas库\data\survey_visited.csv")
survey=pd.read_csv(r"C:\王池池\学习\python\活用pandas库\data\survey_survey.csv")
print(visited)
print(survey)
visited.merge(survey,left_on='ident',right_on='taken')

(3)用户输入

        用户也可以自行创建缺失值,比如依据计算或人工向量来创建向量。对于Series和DataFrame来说,NaN是有效值。

# Series包含缺失值
num_legs=pd.Series({
    'goat':4,
    'amoeba':nan
})
num_legs

# DataFrame包含缺失值
scientists=pd.DataFrame({
    'Name':['Rosaline Franklin','William Gosset'],
    'Occupation':['Chemist','Statistician'],
    'Born':['1920-07-05','1876-06-13'],
    'Died':['1958-04-16','1937-10-16'],
    'missing':[NaN,nan]
})
scientists

(3)重建索引

        如果想向DataFrame添加新索引,并且希望保留其原始值,需要重建索引。一个常见的使用场景是:在一个DataFrame中,其索引表示某段时间,而我们想向DataFrame中添加更多日期。

gapminder=pd.read_csv(r"...\data\gapminder.tsv",sep='\t')
life_exp=gapminder.groupby(['year'])['lifeExp'].mean()
# 取数据子集,然后调用reindex方法
# 取子集
y2000=life_exp[life_exp.index>2000]
print(y2000)
# 调用reindex方法
print(y2000.reindex(range(2000,2010)))

3、处理缺失数据

(1)查找和统计确实数据

        方法1:用count函数统计处理非缺失值的个数,然后用总行数减去不包含缺失值的行数。

        方法2:使用isnull方法

        方法3:使用value_counts方法

# 导入数据
ebola=pd.read_csv(r"...\data\country_timeseries.csv")
# 方法1
# 统计非缺失值的个数
ebola.count()
# 获得总行数
num_rows=ebola.shape[0]
# 总行数减去非缺失值个数
num_missing=num_rows-ebola.count()
print(num_missing)
# 方法2 isnull方法
ebola.isnull().sum()
ebola['Cases_Guinea'].isnull().sum()
# 方法3
ebola.Cases_Guinea.value_counts(dropna=False).head()

(2)清理缺失数据

①重新编码/替换

        使用fillna方法吧缺失值重新编码为其他值。比如把缺失值重新编码为0。如下:

ebola.fillna(0).iloc[0:10,0:5]

②前值填充

        对于缺失值,可以使用内置方法做前值填充(fill forward)或者后值填充(fill backward)。做前值填充时,将按照前一个值填充缺失值。如果某一列以缺失值开始,那么前值填充时,该缺失值将会继续存在。

ebola.fillna(method='ffill').iloc[0:10,0:5]

③后值填充

        与前值填充类似,如果某一列以缺失值结束,那么该缺失值也将继续存在。

ebola.fillna(method='bfill').iloc[:,0:5].tail()

④插值

        插值使用现有值来填充缺失值。填充缺失值的方法有很多种,pandas中的差值方法默认一线性方式填充缺失值。

ebola.interpolate().iloc[0:10,0:5]

⑤删除缺失值

        处理缺失数据的另一种方法是删除含有缺失数据的观测值或变量。不同数据集包含的缺失数据数量不同。对于某些数据集,如果只保留完整数据,那么最终得到的数据集可能是无用的。或许缺失数据不是随机的,删除缺失值后,会得到有偏差的数据集。只保留完整数据也可能导致数据不足,而无法开展分析。

        pandas中可以使用dropna方法删除缺失数据,并且可以通过设置参数控制删除方式。how参数any(只要包含NA值即删除),all(全为NA才删除)。thresh参数允许在删除行或列之前指定NaN值得数量。

ebola_dropna=ebola.dropna(how='any')
ebola_dropna.shape

(3)缺失值计算

        若直接计算中包含缺失值,通常返回缺失值。但如果调用的函数或方法在计算中能忽略缺失值,就另当别论。可以忽略缺失值的内置方法有mean和sum。这些函数通常有skipna参数,通过该参数指定计算时是否要忽略缺失值,通常也是默认忽略。

#缺失值直接参与运算
ebola['Cases_multiple']=ebola['Cases_Guinea']+\
                        ebola['Cases_Liberia']+ebola['Cases_SierraLeone']
ebola_subset=ebola.loc[:,['Cases_Guinea','Cases_Liberia',\
                          'Cases_SierraLeone','Cases_multiple']]
ebola_subset.head()

# skipna参数的默认值为True,表示忽略缺失值
print(ebola.Cases_Guinea.sum())
print(ebola.Cases_Guinea.sum(skipna=False))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值