pandas缺失数据


缺失数据

三种缺失符号

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

print(np.nan == np.nan)

print(np.nan == 0)

print(np.nan == None)

'''
False
False
False
'''

对于布尔类型的列表,如果是np.nan填充,那么它的值会自动变为True而不是False

print(pd.Series([1,np.nan,3],dtype='bool'))

'''
0    True
1    True
2    True
dtype: bool
'''

但当修改一个布尔列表时,会改变列表类型,而不是赋值为True

s = pd.Series([True,False],dtype='bool')
s[1]=np.nan
print(s)

'''
0    1.0
1    NaN
dtype: float64
'''

np.nan相比,None的布尔值为False,只要记住np.nan的几个特性,而None的特性与之相反即可


NA的特性

1、逻辑运算

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

print(True | pd.NA)
print(pd.NA | True)
print(False | pd.NA)
print(False & pd.NA)
print(True & pd.NA)

'''
True
True
<NA>
False
<NA>
'''

2、算术运算和比较运算

这里只需记住除了下面两类情况,其他结果都是NA即可

print(pd.NA ** 0)   # 1
print(1 ** pd.NA)   # 1

convert_dtypes方法

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

print(pd.read_csv('table_missing.csv').convert_dtypes().dtypes)

'''
School      string
Class       string
ID           Int64
Gender      string
Address     string
Height       Int64
Weight       Int64
Math       float64
Physics     string
dtype: object
'''

填充与剔除

dropna函数作用很大,它可以剔除掉无用的NaN缺失值,从列或者行中,或者从特定列或行中搜索缺失值剔除。


问题与习题

问题

【问题一】 如何删除缺失值占比超过25%的列?

percent = df.isna().sum()/len(df)
print(percent)
df.drop(columns=df.columns[percent>=0.25],inplace=True)
print(df.head())

'''
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
  School Class      ID Gender   Address  Height  Math Physics
0    S_1   C_1     NaN      M  street_1     173  34.0      A+
1    S_1   C_1     NaN      F  street_2     192  32.5      B+
2    S_1   C_1  1103.0      M  street_2     186  87.2      B+
3    S_1   NaN     NaN      F  street_2     167  80.4     NaN
4    S_1   C_1  1105.0    NaN  street_4     159  84.8      A-
'''

【问题二】 什么是Nullable类型?请谈谈为什么要引入这个设计?

Nullable类型是pandas的扩展类型,用于表示标量的缺失值且不改变数据类型。
其目的就是为了(在若干版本后)解决之前出现的混乱局面,统一缺失值处理方法。


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

  • 通过isna(),info()等方法整体了解每行每列缺失值情况,统计缺失比例,了解缺失程度

习题

【练习一】现有一份虚拟数据集,列类型分别为string/浮点/整型,请解决如下问题:
(a)请以列类型读入数据,并选出C为缺失值的行。
(b)现需要将A中的部分单元转为缺失值,单元格中的最小转换概率为25%,且概率大小与所在行B列单元的值成正比。

df1 = pd.read_csv('Missing_data_one.csv')

print(df1[df1['C'].isna()])

'''
          A      B   C
1   not_NaN  0.700 NaN
5   not_NaN  0.972 NaN
11  not_NaN  0.736 NaN
19  not_NaN  0.684 NaN
21  not_NaN  0.913 NaN
'''

第二小题想不明白。贴出参考答案。

min_b = df1['B'].min()
df1['A'] = pd.Series(list(zip(df1['A'].values
                    ,df1['B'].values))).apply(lambda x:x[0] if np.random.rand()>0.25*x[1]/min_b else np.nan)
print(df1.head())

'''
         A      B     C
0      NaN  0.922   4.0
1  not_NaN  0.700   NaN
2  not_NaN  0.503   8.0
3      NaN  0.938   4.0
4  not_NaN  0.952  10.0
'''

【练习二】 现有一份缺失的数据集,记录了36个人来自的地区、身高、体重、年龄和工资,请解决如下问题:
(a)统计各列缺失的比例并选出在后三列中至少有两个非缺失值的行。
(b)请结合身高列和地区列中的数据,对体重进行合理插值。

真~想到头皮发麻
还是想不出来。
我们来看看别人的优秀程序。

df2 = pd.read_csv('Missing_data_two.csv')
print(df2.isna().sum())
percent2 = df2.isna().sum() / len(df2)
print(percent2)

column_list = df2.columns[-3:]
df2_isna = df2[df2[column_list].isna().sum(1)<=1]
print(df2_isna).head()

'''
编号    0.000000
地区    0.000000
身高    0.000000
体重    0.222222
年龄    0.250000
工资    0.222222
dtype: float64
   编号 地区      身高     体重    年龄       工资
0   1  A  157.50    NaN  47.0  15905.0
1   2  B  202.00  91.80  25.0      NaN
3   4  A  166.61  59.95  77.0   5434.0
4   5  B  185.19    NaN  62.0   4242.0
5   6  A  187.13  78.42  55.0  13959.0
'''
df3 = df2.copy()
df_group = df3.groupby('地区')
df_group.head()
for temp in df_group:
    df_group_temp = temp[1]
    df3.loc[df_group_temp.index, '体重'] = df_group_temp[['身高', '体重']].sort_values(by='身高').interpolate()['体重']
print(df3.head())

'''
   编号 地区      身高     体重    年龄       工资
0   1  A  157.50  53.58  47.0  15905.0
1   2  B  202.00  91.80  25.0      NaN
2   3  C  169.09  62.18   NaN      NaN
3   4  A  166.61  59.95  77.0   5434.0
4   5  B  185.19  81.75  62.0   4242.0
'''
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值