1. 处理缺失值
判断数据中是否包含NaN: pd.isnull(df);pd.notnull(df)
存在缺失值nan:
删除存在缺失值的:dropna(axis='rows')
不会修改原数据,需要接受返回值;
替换缺失值:fillna(value, inplace=True)
value:替换成的值;inplace = True:会修改原数据,False:不替换修改原数据,生成新的对象
如果缺失值没有使用NaN标记,比如使用 " ?"先替换为np.nan,然后继续处理。
1.1 缺失值的类型
Python自带的None,是Python中的空对象。None不能参与到任何计算中。
object类型的运算要比int类型的运算慢得多。
Pandas中None与np.nan都视作np.nan。
np.nan是浮点类型,能参与到计算中。但计算的结果总是NaN。
可以使用np.nan*()函数来计算,此时会过滤掉nan。
比如np.nansum(df)
1.2 判断函数
isnull() notnull()
df
df.isnull()
df.notnull()
all() : 必须全部为True才会是True,类似and
any() : 只要有一个为True就为True,类似or
# 找有空的列
df.isnull().any() # 尽可能找到有空的列或行
# df.isnull().all() # 必须全部都为空的行或列才会为True
# 找没有空的列
df.notnull().all() # 尽量找没有空值的列或行
# df.notnull().any()
# 找有空的行
df.isnull().any(axis=1)
# 找没有空的行
df.notnull().all(axis=1)
使用bool值索引过滤数据:
# 行过滤
cond = df.isnull().any(axis=1)
# display(~cond) # 取反
df[~cond]
cond = df.notnull().all(axis=1)
df[cond]
# 过滤列
cond = df.isnull().any()
df.loc[:, ~cond]
cond = df.notnull().all()
df.loc[:, cond]
1.3 过滤函数
dropna():可以选择过滤的是行还是列(默认为行)。
使用dropna的前提是,缺失值的类型必须是np.nan。
# 默认删除有空的行
df.dropna()
df.dropna(axis=1) # 删除有空的列
也可以选择过滤的方式 how = 'all':
df.dropna(how='any')
# 必须所有数据都为nan才会删除
df.dropna(how='all', axis=1)
inplace=True 修改原数据:
df2 = df.copy()
df2
# inplace=True 修改原数据
df2.dropna(inplace=True)
df2
替换所有缺失值:
for i in movie.columns:
if np.all(pd.notnull(movie[i])) == False:
print(i)
movie[i].fillna(movie[i].mean(), inplace=True)
缺失值不是nan类型的,有默认标记的 :
以上数据在读取时,可能会报如下错误:
URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)>
解决办法:
# 全局取消证书验证
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
先替换 ‘?’ 为np.nan:
df.replace(to_replace=, value=)
to_replace:替换前的值;value:替换后的值
# 把一些其它值标记的缺失值,替换成np.nan
wis = wis.replace(to_replace='?', value=np.nan)
# 在进行缺失值的处理
# 删除
wis = wis.dropna()
1.4 填充函数
fillna(value, inplace=True)
value:替换成的值;inplace = True:会修改原数据;False:不替换修改原数据,生成新的对象
# 填充nan
df.fillna(value=100)
df2 = df.copy()
df2.loc[1, 'B'] = np.nan
df2.loc[2, 'C'] = np.nan
df2
# limit: 限制填充的次数
df2.fillna(value=100, limit=1, inplace=True)
可以选择前向填充还是后向填充:
df.fillna(method='ffill') # 向前填充
df.fillna(method='backfill') # 向后填充
# method : {'backfill', 'bfill', 'pad', 'ffill', None}, default None
# Method to use for filling holes in reindexed Series
# pad / ffill: propagate last valid observation forward to next valid
# backfill / bfill: use next valid observation to fill gap.
df.fillna(method='ffill', axis=1) # 向左填充
df.fillna(method='backfill', axis=1) # 向右填充