空值处理
pandas对缺失值的处理
pandas使用这些函数处理缺失值:
isnull和notnull:检测是否是空值,可用于df和series
dropna:丢弃、删除缺失值
axis:删除行还是列,{ 0 or 'index' 按行删除 , 1 or 'column' 按列删除},default 0
how:如果等于any则任何值为空都删除,如果等于all则所有值为空才删除
inplace:如果为True,则修改当前df,否则返回新的df
fillna:填充空值
value:用于填充的值。可以是单个值,或者字典(key是列名,value是值)
method:等于ffill时使用前一个不为空的值填充forword fill,等于bfill使用后一个不为空的值填充backword fill
axis:按行还是列填充,{ 0 or 'index' , 1 or 'column'}
inplace:如果为True,则修改当前df,否则返回新的df
python缺失值有3种:
1)Python内置的None值。None,使用df['date'].isnull()进行判断是否为空值。
2)在pandas中,将缺失值表示为NA,表示不可用not available。
3)对于数值数据,pandas使用浮点值NaN(Not a Number)表示缺失数据。
所以,缺失值有3种:None,NA,NaN
import pandas as pd
实例:特殊excel的读取、清洗、处理
步骤1:读取excel的时候,忽略前几个空行
study=pd.read_excel('student.xlsx',skiprows=4)
study
<tr style="text-align: right;">
<th></th>
<th>Unnamed: 0</th>
<th>Unnamed: 1</th>
<th>姓名</th>
<th>科目</th>
<th>分数</th>
</tr>
<tr>
<th>0</th>
<td>NaN</td>
<td>NaN</td>
<td>小明</td>
<td>语文</td>
<td>85.0</td>
</tr>
<tr>
<th>1</th>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>数学</td>
<td>80.0</td>
</tr>
<tr>
<th>2</th>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>英语</td>
<td>90.0</td>
</tr>
<tr>
<th>3</th>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
</tr>
<tr>
<th>4</th>
<td>NaN</td>
<td>NaN</td>
<td>小王</td>
<td>语文</td>
<td>85.0</td>
</tr>
<tr>
<th>5</th>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>数学</td>
<td>NaN</td>
</tr>
<tr>
<th>6</th>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>英语</td>
<td>90.0</td>
</tr>
<tr>
<th>7</th>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
</tr>
<tr>
<th>8</th>
<td>NaN</td>
<td>NaN</td>
<td>小刚</td>
<td>语文</td>
<td>85.0</td>
</tr>
<tr>
<th>9</th>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>数学</td>
<td>80.0</td>
</tr>
<tr>
<th>10</th>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>英语</td>
<td>90.0</td>
</tr>
步骤2:检测空值
study.isnull()
<tr style="text-align: right;">
<th></th>
<th>Unnamed: 0</th>
<th>Unnamed: 1</th>
<th>姓名</th>
<th>科目</th>
<th>分数</th>
</tr>
<tr>
<th>0</th>
<td>True</td>
<td>True</td>
<td>False</td>
<td>False</td>
<td>False</td>
</tr>
<tr>
<th>1</th>
<td>True</td>
<td>True</td>
<td>True</td>
<td>False</td>
<td>False</td>
</tr>
<tr>
<th>2</th>
<td>True</td>
<td>True</td>
<td>True</td>
<td>False</td>
<td>False</td>
</tr>
<tr>
<th>3</th>
<td>True</td>
<td>True</td>
<td>True</td>
<td>True</td>
<td>True</td>
</tr>
<tr>
<th>4</th>
<td>True</td>
<td>True</td>
<td>False</td>
<td>False</td>
<td>False</td>
</tr>
<tr>
<th>5</th>
<td>True</td>
<td>True</td>
<td>True</td>
<td>False</td>
<td>True</td>
</tr>
<tr>
<th>6</th>
<td>True</td>
<td>True</td>
<td>True</td>
<td>False</td>
<td>False</td>
</tr>
<tr>
<th>7</th>
<td>True</td>
<td>True</td>
<td>True</td>
<td>True</td>
<td>True</td>
</tr>
<tr>
<th>8</th>
<td>True</td>
<td>True</td>
<td>False</td>
<td>False</td>
<td>False</td>
</tr>
<tr>
<th>9</th>
<td>True</td>
<td>True</td>
<td>True</td>
<td>False</td>
<td>False</td>
</tr>
<tr>
<th>10</th>
<td>True</td>
<td>True</td>
<td>True</td>
<td>False</td>
<td>False</td>
</tr>
study['分数'].isnull()
0 False
1 False
2 False
3 True
4 False
5 True
6 False
7 True
8 False
9 False
10 False
Name: 分数, dtype: bool
study['姓名'].notnull()
0 True
1 False
2 False
3 False
4 True
5 False
6 False
7 False
8 True
9 False
10 False
Name: 姓名, dtype: bool
study['姓名'].notna()
0 True
1 False
2 False
3 False
4 True
5 False
6 False
7 False
8 True
9 False
10 False
Name: 姓名, dtype: bool
# 筛选没有空分数的所有行
study.loc[study['分数'].notnull(),:]
<tr style="text-align: right;">
<th></th>
<th>Unnamed: 0</th>
<th>Unnamed: 1</th>
<th>姓名</th>
<th>科目</th>
<th>分数</th>
</tr>
<tr>
<th>0</th>
<td>NaN</td>
<td>NaN</td>
<td>小明</td>
<td>语文</td>
<td>85.0</td>
</tr>
<tr>
<th>1</th>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>数学</td>
<td>80.0</td>
</tr>
<tr>
<th>2</th>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>英语</td>
<td>90.0</td>
</tr>
<tr>
<th>4</th>
<td>NaN</td>
<td>NaN</td>
<td>小王</td>
<td>语文</td>
<td>85.0</td>
</tr>
<tr>
<th>6</th>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>英语</td>
<td>90.0</td>
</tr>
<tr>
<th>8</th>
<td>NaN</td>
<td>NaN</td>
<td>小刚</td>
<td>语文</td>
<td>85.0</td>
</tr>
<tr>
<th>9</th>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>数学</td>
<td>80.0</td>
</tr>
<tr>
<th>10</th>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
<td>英语</td>
<td>90.0</td>
</tr>
步骤3: 删除掉全是空值的列
study.dropna(axis=1,how='all',inplace=True)
study
<tr style="text-align: right;">
<th></th>
<th>姓名</th>
<th>科目</th>
<th>分数</th>
</tr>
<tr>
<th>0</th>
<td>小明</td>
<td>语文</td>
<td>85.0</td>
</tr>
<tr>
<th>1</th>
<td>NaN</td>
<td>数学</td>
<td>80.0</td>
</tr>
<tr>
<th>2</th>
<td>NaN</td>
<td>英语</td>
<td>90.0</td>
</tr>
<tr>
<th>3</th>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
</tr>
<tr>
<th>4</th>
<td>小王</td>
<td>语文</td>
<td>85.0</td>
</tr>
<tr>
<th>5</th>
<td>NaN</td>
<td>数学</td>
<td>NaN</td>
</tr>
<tr>
<th>6</th>
<td>NaN</td>
<td>英语</td>
<td>90.0</td>
</tr>
<tr>
<th>7</th>
<td>NaN</td>
<td>NaN</td>
<td>NaN</td>
</tr>
<tr>
<th>8</th>
<td>小刚</td>
<td>语文</td>
<td>85.0</td>
</tr>
<tr>
<th>9</th>
<td>NaN</td>
<td>数学</td>
<td>80.0</td>
</tr>
<tr>
<th>10</th>
<td>NaN</td>
<td>英语</td>
<td>90.0</td>
</tr>
步骤4:删除掉全是空值的列
study.dropna(axis=0,how='all',inplace=True)
study
<tr style="text-align: right;">
<th></th>
<th>姓名</th>
<th>科目</th>
<th>分数</th>
</tr>
<tr>
<th>0</th>
<td>小明</td>
<td>语文</td>
<td>85.0</td>
</tr>
<tr>
<th>1</th>
<td>NaN</td>
<td>数学</td>
<td>80.0</td>
</tr>
<tr>
<th>2</th>
<td>NaN</td>
<td>英语</td>
<td>90.0</td>
</tr>
<tr>
<th>4</th>
<td>小王</td>
<td>语文</td>
<td>85.0</td>
</tr>
<tr>
<th>5</th>
<td>NaN</td>
<td>数学</td>
<td>NaN</td>
</tr>
<tr>
<th>6</th>
<td>NaN</td>
<td>英语</td>
<td>90.0</td>
</tr>
<tr>
<th>8</th>
<td>小刚</td>
<td>语文</td>
<td>85.0</td>
</tr>
<tr>
<th>9</th>
<td>NaN</td>
<td>数学</td>
<td>80.0</td>
</tr>
<tr>
<th>10</th>
<td>NaN</td>
<td>英语</td>
<td>90.0</td>
</tr>
步骤5:将分数列为空的填充为0分
study.fillna({'分数':0},inplace=True)
# 等同于
study['分数']=study['分数'].fillna(0)
study
<tr style="text-align: right;">
<th></th>
<th>姓名</th>
<th>科目</th>
<th>分数</th>
</tr>
<tr>
<th>0</th>
<td>小明</td>
<td>语文</td>
<td>85.0</td>
</tr>
<tr>
<th>1</th>
<td>NaN</td>
<td>数学</td>
<td>80.0</td>
</tr>
<tr>
<th>2</th>
<td>NaN</td>
<td>英语</td>
<td>90.0</td>
</tr>
<tr>
<th>4</th>
<td>小王</td>
<td>语文</td>
<td>85.0</td>
</tr>
<tr>
<th>5</th>
<td>NaN</td>
<td>数学</td>
<td>0.0</td>
</tr>
<tr>
<th>6</th>
<td>NaN</td>
<td>英语</td>
<td>90.0</td>
</tr>
<tr>
<th>8</th>
<td>小刚</td>
<td>语文</td>
<td>85.0</td>
</tr>
<tr>
<th>9</th>
<td>NaN</td>
<td>数学</td>
<td>80.0</td>
</tr>
<tr>
<th>10</th>
<td>NaN</td>
<td>英语</td>
<td>90.0</td>
</tr>
步骤6:将姓名的缺失值填充
使用前面的有效填充,用ffill:forward
study.loc[:,'姓名']=study['姓名'].fillna(method='ffill')
study
<tr style="text-align: right;">
<th></th>
<th>姓名</th>
<th>科目</th>
<th>分数</th>
</tr>
<tr>
<th>0</th>
<td>小明</td>
<td>语文</td>
<td>85.0</td>
</tr>
<tr>
<th>1</th>
<td>小明</td>
<td>数学</td>
<td>80.0</td>
</tr>
<tr>
<th>2</th>
<td>小明</td>
<td>英语</td>
<td>90.0</td>
</tr>
<tr>
<th>4</th>
<td>小王</td>
<td>语文</td>
<td>85.0</td>
</tr>
<tr>
<th>5</th>
<td>小王</td>
<td>数学</td>
<td>0.0</td>
</tr>
<tr>
<th>6</th>
<td>小王</td>
<td>英语</td>
<td>90.0</td>
</tr>
<tr>
<th>8</th>
<td>小刚</td>
<td>语文</td>
<td>85.0</td>
</tr>
<tr>
<th>9</th>
<td>小刚</td>
<td>数学</td>
<td>80.0</td>
</tr>
<tr>
<th>10</th>
<td>小刚</td>
<td>英语</td>
<td>90.0</td>
</tr>
步骤7:将清洗好的excel保存
# 去掉自动生成索引
# 保存到文件中
study.to_excel('student_clean.xlsx',index=False)