使用 df[df.isnull().T.any()] 可列出数据框 df 中所有包含空值的行。其中 isnull() 能够判断数据中元素是否为空值; T 为行列转置; any() 判断该行是否有空值。
df[df.isnull().T.any()]
df
isnull()
T
any()
import pandas as pd from tabulate import tabulate # 创建一个示例 DataFrame data = { 'Column1': [1, None, 3, None], 'Column2': [4, None, None, None], 'Column3': [7, 8, 9, None], 'Column4': [7, 8, 9, None] df = pd.DataFrame(data) print("原始 DataFrame:") print(tabulate(df)) # 列出所有空白值 print("列出所有空白值:") print(tabulate(df[df.isnull().T.any()]))
原始 DataFrame: - --- --- --- --- 0 1 4 7 7 1 nan nan 8 8 2 3 nan 9 9 3 nan nan nan nan - --- --- --- --- 列出所有空白值: - --- --- --- --- 1 nan nan 8 8 2 3 nan 9 9 3 nan nan nan nan - --- --- --- ---
dropna 是 Pandas 库中用于删除 DataFrame 或 Series 中的缺失值(如 NaN 或 None)的一个非常有用的方法。它提供了多种选项来定制缺失值的处理方式。以下是 dropna 方法的一些关键特性和使用方式:
dropna
DataFrame.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
axis=0
'index'
axis=1
'columns'
'any'
'all'
how
thresh
False
True
Pandas中对数据框的绝大多数操作(例如删除空值)在默认情况下, 不修改数据框自身数据 。如果要得到修改后的结果,可用一个变量来进行保存,或者查看函数有无 inplace 参数,将 inplace 设置为 True ,则会对数据框本身进行修改。建议使用变量接收修改后的数据框,而不是直接修改原有数据框。
inplace
在有些时候,我们简单地将某行数据删除,是不太理想的选择。我们可以使用一些值填充空值,如我们使用 未知 或 其他 填充变量 城市 的值,使用 0 填充未填的多选题选项等等。
未知
其他
城市
0
Pandas 提供了fillna方法填充缺失值,具体参数如下:
value
method
{‘backfill’, ‘bfill’, ‘pad’, ‘ffill’, None}
None
pad / ffill
backfill / bfill
limit
axis
1
# 将 NaN 值替换为 0 df_filled = df.fillna(0) print("\n填充后的 DataFrame:") print(df_filled)
异常值可能是由于数据录入错误、测量错误或数据传输错误等原因造成的,处理这些值可以提高数据集的整体质量。异常值可能会扭曲统计分析的结果,如影响均值、标准差等统计量的计算,导致分析结果不准确。
对于类别变量,可以通过描述统计,计算出每个变量不同取值出现的次数,这样,就可以看到类别变量的取值,是否是类别变量应有的值。比如,性别,应该只有男性和女性,如果出现其它类别,可能就是输入时产生的错误。
import pandas as pd # 示例数据 data = {'颜色': ['红', '蓝', '绿', '红', '黄', '紫', '红', '绿', '蓝', '黄', '蓝色']} df = pd.DataFrame(data) # 频率分析 value_counts = df['颜色'].value_counts() print(value_counts) # 假设“蓝色”是一个拼写错误,它应该是“蓝” # 这里“蓝色”可能是一个异常值
使用 replace 方法,可以替换取值。
replace
# 将“颜色”列中的“蓝色”替换为“蓝” df['颜色'] = df['颜色'].replace('蓝色', '蓝') # 频率分析 value_counts = df['颜色'].value_counts() print(value_counts)
识别数值变量的异常值是数据清理过程中的一个重要步骤。异常值(也称为离群点)是那些显著偏离数据集中其他数据点的值。以下是识别连续数值变量异常值的几种常用方法:
异常值 = mean ± 3 * std
异常值 < Q1 - 1.5 * IQR
异常值 > Q3 + 1.5 * IQR
还可利用箱线图可视化地识别异常值。箱线图基于四分位数和中位数,其中箱子的“须”通常定义为 1.5 * IQR。箱线图外的点通常视为异常值。使用箱线图可视化识别异常值的原理,还是利用四分位数(Q1, Q3)和四分位数范围(IQR = Q3 - Q1)来识别异常值。
import pandas as pd # 示例数据 data = {'value': [10, 12, 12, 13, 12, 11, 10, 29, 30, 11, 10, 100]} df = pd.DataFrame(data) # 计算均值和标准差 mean = df['value'].mean() std = df['value'].std() condition1 = (df['value'] < mean - 3 * std) | (df['value'] > mean + 3 * std) # 识别异常值 outliers1 = df[condition1] print('使用标准差判断的异常值为:',outliers1) # 计算 IQR Q1 = df['value'].quantile(0.25) Q3 = df['value'].quantile(0.75) IQR = Q3 - Q1 # 识别异常值 outliers2 = df[(df['value'] < Q1 - 1.5 * IQR) | (df['value'] > Q3 + 1.5 * IQR)] print('使用IQR判断的异常值为:',outliers2)
使用标准差判断的异常值为: value 11 100 使用IQR判断的异常值为: value 7 29 8 30 11 100
判断为异常值的数值变量取值,可以做删除处理。
# 删除异常值 df_cleaned = df[~condition1] print("清理后:", df_cleaned.shape,'清理前:',df.shape)
清理后: (11, 1) 清理前: (12, 1)
condition1 是一个布尔系列,表示每行数据是否是异常值。 ~condition1 是对这个条件取反,意味着选择非异常值的行。 df[~condition1] 则过滤掉了异常值,只保留了正常的数据。
condition1
~condition1
df[~condition1]
在数据录入或数据合并时,可能会产生重复值,有的重复值是完全相同,有的重复值是个别变量值相同。在数据清理时,应区别对待。
duplicated() 函数的功能是检查数据中是否有重复值,用于标记 Series 中的值、DataFrame 中的记录行是否重复,重复为 True ,不重复为 False 。每行数据都是和它前面的记录相比较。该函数返回一个由布尔值组成的系列(Series)。
duplicated()
pandas.Series.duplicated(subset=None, keep='first')
keep 参数的 3 种取值:
keep
3
first
last
subset 用来指定特定的列,默认所有列。
subset
drop_duplicates()
ingoore_index
df.drop_duplicates(subset=['A','B'],keep='first',inplace=True)
统计分析时,变量的类别决定了能采用的统计分析方法。适用于数值变量的统计分析方法,多数不适用于类别变量。故在数据分析前,对数据中涉及到的变量,要按照变量本身的特征正确合理的划分类别。
category
int
float
string
datetime64
DataFrame.dtypes 属性将返回DataFrame中所有变量的类型。
DataFrame.dtypes
import pandas as pd df_movie = pd.read_csv(R'../../data/csv/movie.csv') df_movie.dtypes
id float64 average float64 country object genre object language object release_date object title object votes float64 dtype: object
pandas提供了 astype 方法,能按照传入的要求,对列中变量类型进行设置。
astype
下面的语句,将 df 中的 id 列设为 int 类型,将 release_date 设为 datetime64 类型,将 title 列设为 string 类型, vote 列设为 int64 类型:
id
release_date
title
vote
int64
df_movie.dropna(how='any',inplace=True) df_movie.astype({"id": "int", "release_date": "datetime64[ns]", "title": "string", "votes": "int64"}).dtypes
id int32 average float64 country object genre object language object release_date datetime64[ns] title string[python] votes int64 dtype: object
dataframe.astype('category')
df2 = df.astype({"产地": "category"})
series.cat.categories
df2['产地'].cat.categories
series.cat.add_categories
df2['产地'].cat.add_categories(['俄罗斯'],inplace=True)
series.cat.romove_categories
df2['产地'].cat.remove_categories(['俄罗斯'],inplace=True)
df2.产地.cat.rename_categories({'印度': 'India',},inplace=True)
顺序变量可以排序,因此在指定变量为顺序变量时,需要提供排序信息。
from pandas.api.types import CategoricalDtype cat_type = CategoricalDtype(categories=['一星', '二星', '三星', '四星', '五星'], ordered=True) df3['星级'].astype(cat_type)
as_ordered
df2 = df.astype({"星级": "category"}) df2['星级'].cat.as_ordered()
cat.reorder_categories
df[column].cat.reorder_categories(['Low', 'Medium', 'High'])
使用cut方法,能将数值变量按照设定的范围,转化为有序类别变量。
df_movie['星级'] = pd.cut(df['average'], bins=[0, 2, 4, 6, 8, 10], labels=['一星', '二星', '三星', '四星', '五星']) df_movie['星级'].dtype
CategoricalDtype(categories=['一星', '二星', '三星', '四星', '五星'], ordered=True)
逻辑一致性检查是指通过变量之间的逻辑关系是否合理进行数据有效性的检查。例如调查对象在填写问卷时,如果没有认真阅读题目及选项内容,可能会产生前后矛盾的回答,如在选择了没有子女的情况下,又填写了子女教育的支出估计范围。为了提高数据的质量,研究人员最好在设计问卷时就准备了一些逻辑上相关的冗余性的题目,用来筛选或排除存在内在逻辑错误的问卷。
逻辑一致性检查可以通过构造pandas查询条件或索引进行检查。
import pandas # 打开SPSS文件 df_raw = pandas.read_spss(r'../../data/sav/identity.sav') # 使用query condition = '会以中国人自豪吗=="会" and 会隐瞒身份吗=="一定会"' # 取得逻辑不一致数据的序号列表 result = df_raw.query(condition).index print(result) # 使用drop函数删除指定 df_raw.drop(index=result,inplace=True)
Index([ 54, 70, 75, 161, 191, 236, 240, 251, 323, 338, 406, 428, 525, 576, 578, 579, 593, 595, 607, 665, 667, 679, 764, 770, 783, 784, 809, 839, 869, 899], dtype='int64')
import pandas as pd # 示例数据 data = { '年龄': [25, 30, -5, 40], '入职日期': ['2020-01-01', '2019-05-20', '2021-07-15', '2018-03-10'], '离职日期': ['2021-01-01', '2020-05-20', None, '2019-03-10'] df = pd.DataFrame(data) # 范围检查:年龄应该大于 0 df['年龄检查'] = df['年龄'] > 0 # 格式检查:检查日期格式是否正确(这里简化为检查是否为 None) df['入职日期检查'] = df['入职日期'].notna() df['离职日期检查'] = df['离职日期'].notna() # 逻辑关系检查:入职日期应该早于或等于离职日期 df['日期逻辑检查'] = pd.to_datetime(df['入职日期']) <= pd.to_datetime(df['离职日期']) print(tabulate(df, headers='keys'))
年龄 入职日期 离职日期 年龄检查 入职日期检查 离职日期检查 日期逻辑检查 -- ------ ---------- ---------- ---------- -------------- -------------- -------------- 0 25 2020-01-01 2021-01-01 True True True True 1 30 2019-05-20 2020-05-20 True True True True 2 -5 2021-07-15 False True False False 3 40 2018-03-10 2019-03-10 True True True True