Datawhale干货
作者:耿远昊,Datawhale成员,华东师范大学
Pandas 是一个强大的分析结构化数据的工具集,它的使用基础是Numpy(提供高性能的矩阵运算),用于数据挖掘和数据分析,同时也提供数据清洗功能。
在往期文章中,已经详细讲解了Pandas做分析数据的四种基本操作:索引、分组、变形及合并。现在,开始正式介绍Pandas的数据结构类型:缺失数据、文本数据、分类数据和时序数据。
在接下来的两章中,会接触到数据预处理中比较麻烦的类型,即缺失数据和文本数据(尤其是混杂型文本)。今天,我们首先对缺失数据进行系统地梳理。
本文目录
1. 基础概念
1.1. 缺失值分类
1.2. 缺失值处理方法
2. 缺失观测及其类型
2.2. 三种缺失符号
2.3. Nullable类型与NA符号
2.4. NA的特性
2.5. convert_dtypes方法
3. 缺失数据的运算与分组
3.1. 加号与乘号规则
3.2. groupby方法中的缺失值
4. 填充与剔除
4.1. fillna方法
4.2. dropna方法
5. 插值
5.1. 线性插值
5.2. 高级插值方法
5.3. interpolate中的限制参数
6. 问题及练习
6.1. 问题
6.2. 练习
import pandas as pd
import numpy as np
df = pd.read_csv('data/table_missing.csv')
df.head()
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)]
np.nan == np.nan
np.nan == 0
np.nan == None
df.equals(df)
type(np.nan)
pd.Series([1,2,3]).dtype
pd.Series([1,np.nan,3]).dtype
pd.Series([1,np.nan,3],dtype='bool')
s = pd.Series([True,False],dtype='bool')
s[1]=np.nan
s
df['ID'].dtype
df['Math'].dtype
df['Class'].dtype
None == None
pd.Series([None],dtype='bool')
s = pd.Series([True,False],dtype='bool')
s[0]=None
s
s = pd.Series([1,0],dtype='bool')
s[0]=None
s
type(pd.Series([1,None])[1])
type(pd.Series([1,None],dtype='O')[1])
pd.Series([None]).equals(pd.Series([np.nan]))
s_time = pd.Series([pd.Timestamp('20120101')]*5)
s_time
s_time[2] = None
s_time
s_time[2] = np.nan
s_time
s_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
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
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]
s = pd.Series(['dog','cat'],dtype='string')
s
s[0] = np.nan
s
s[0] = None
s
s[0] = pd.NaT
s
s = pd.Series(["a", None, "b"], dtype="string")
s.str.count('a')
s2 = pd.Series(["a", None, "b"], dtype="object")
s2.str.count("a")
s.str.isdigit()
s2.str.isdigit()
True | pd.NA
pd.NA | True
False | pd.NA
False & pd.NA
True & pd.NA
#bool(pd.NA)
pd.NA ** 0
1 ** pd.NA
pd.NA + 1
"a" * pd.NA
pd.NA == pd.NA
pd.NA < 2.5
np.log(pd.NA)
np.add(pd.NA, 1)
pd.read_csv('data/table_missing.csv').dtypes
pd.read_csv('data/table_missing.csv').convert_dtypes().dtypes
s = pd.Series([2,3,np.nan,4])
s.sum()
s.prod()
s.cumsum()
s.cumprod()
s.pct_change()
df_g = pd.DataFrame({'one':['A','B','C','D',np.nan],'two':np.random.randn(5)})
df_g
df_g.groupby('one').groups
df['Physics'].fillna('missing').head()
df['Physics'].fillna(method='ffill').head()
df['Physics'].fillna(method='backfill').head()
df_f = pd.DataFrame({'A':[1,3,np.nan],'B':[2,4,np.nan],'C':[3,5,np.nan]})
df_f.fillna(df_f.mean())
df_f.fillna(df_f.mean()[['A','B']])
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)
df_d.dropna(axis=1,how='all')
df_d.dropna(axis=0,subset=['B','C'])
s = pd.Series([1,10,15,-5,-2,np.nan,np.nan,28])
s
s.interpolate()
s.interpolate().plot()
s.index = np.sort(np.random.randint(50,300,8))
s.interpolate()
#值不变
s.interpolate().plot()
#后面三个点不是线性的(如果几乎为线性函数,请重新运行上面的一个代码块,这是随机性导致的)
s.interpolate(method='index').plot()
#可以看到与上面的区别
s_t = pd.Series([0,np.nan,10]
,index=[pd.Timestamp('2012-05-01'),pd.Timestamp('2012-05-07'),pd.Timestamp('2012-06-03')])
s_t
s_t.interpolate().plot()
s_t.interpolate(method='time').plot()
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()
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')
df.loc[:,(df.isna().sum()/df.isna().count()<0.25).values]
q1 = pd.read_csv('data/Missing_data_one.csv')
q1.head()
A B C
0 not_NaN 0.922 4.0
1 not_NaN 0.700 NaN
2 not_NaN 0.503 8.0
3 not_NaN 0.938 4.0
4 not_NaN 0.952 10.0
q1[q1['C'].isna()]
q1['A'] = pd.Series(list(zip(q1['A'].values,q1['B'].values))).apply(lambda x:x[0] if np.random.rand()>0.25*x[1]/q1['B'].min() else np.nan)
pd.read_csv('data/Missing_data_two.csv').head()
编号 地区 身高 体重 年龄 工资
0 1 A 157.50 NaN 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 NaN 62.0 4242.0
q2.isna().sum()/q2.shape[0]
q2[q2.iloc[:,-3:].isna().sum(1)<=1].head()
q2_new = q2.copy()
for area,group in q2.groupby('地区'):
q2_new.loc[group.index,'体重'] = group[['身高','体重']].sort_values(by='身高').interpolate()['体重']
q2_new = q2_new.round(decimals=2)
q2_new.head()
标签:数据分析,df,Series,nan,np,pd,dtype,数据处理,Pandas
From: https://blog.51cto.com/u_15699042/6963140