Pandas基础06 异常值的检测与过滤
在数据分析中,异常值(Outliers)是指与其他数据点显著不同的值。这些值可能由于数据录入错误、设备故障或极端情况而产生,因此在进行数据分析之前,需要对其进行检测与过滤。本文将介绍如何利用 Pandas 中的一些常见函数,检测、处理和过滤数据中的异常值,同时对数据进行基本的处理和探索。
3.5.1. describe()
:查看每一列的描述性统计量
describe()
函数是 Pandas 中最常用的查看数据分布的工具之一。它可以帮助我们了解每一列的基本统计信息,包括计数、均值、标准差、最小值、最大值以及四分位数等。通过这些信息,我们可以初步识别数据中的异常值。
import pandas as pd
import numpy as npdf = pd.DataFrame(np.random.randint(1, 100, (4, 3)), index=["zhangsan", "lisi", "wangwu", "zhouliu"], columns=["Chinese", "Math", "English"])# 查看描述性统计量
df.describe()
输出结果:
Chinese Math English
count 4.000000 4.000000 4.000000
mean 85.750000 36.750000 25.250000
std 13.022417 26.474831 19.397165
min 74.000000 11.000000 7.000000
25% 74.750000 16.250000 9.250000
50% 85.500000 35.000000 25.500000
75% 96.500000 55.500000 41.500000
max 98.000000 66.000000 43.000000
通过 describe()
输出的统计数据,我们可以观察到各列的均值、标准差以及最大最小值。如果某一列的最小值或最大值显得非常偏离其他数据点,这可能意味着该列中有异常值。
3.5.2. info()
:查看数据信息
info()
函数可以帮助我们快速查看 DataFrame 的结构,包括行数、列数、每列的非空值数量以及数据类型等。这对于检查数据完整性和结构非常有用。
df.info()
输出结果:
<class 'pandas.core.frame.DataFrame'>:数据结构为DataFrame
Index: 4 entries, zhangsan to zhouliu:行索引
Data columns (total 3 columns): :列索引# Column Non-Null Count Dtype :列的信息
--- ------ -------------- -----0 Chinese 4 non-null int32 :4个均为非空值1 Math 4 non-null int322 English 4 non-null int32
dtypes: int32(3) :元素的类型
memory usage: 80.0+ bytes :内存中的存储情况
通过 info()
,我们得知所有列的数据类型均为 int32
,且每列都没有缺失值。这有助于确认数据是否完整且正确。
3.5.3. std()
:标准差
标准差是衡量数据分散程度的一个指标。标准差较大的列可能存在更多的异常值,因为数据点的波动幅度较大。我们可以通过 std()
函数来计算每列数据的标准差,并作为识别异常值的一个辅助指标。
df.std()
输出结果:
Chinese 13.022417
Math 26.474831
English 19.397165
dtype: float64
如果某一列的标准差非常大,且数据的分布范围较广,则可能存在一些离群点或异常值。
3.5.4. drop()
:删除特定索引
drop()
函数可以帮助我们删除 DataFrame 中的特定行或列。如果在数据中发现了明显的异常值或错误数据,可以使用 drop()
来移除这些数据。
df1 = df.copy()
df1.drop("zhangsan") # 删除行
df1.drop(index="zhangsan") # 删除行df1.drop("Chinese", axis=1) # 删除列
df1.drop(columns=["Chinese", "Math"], inplace=True) # 删除多列并覆盖原数据
在数据清理过程中,删除异常值或者错误数据是常见的操作,drop()
函数提供了简单且灵活的方式来删除不需要的数据。
3.5.5. unique()
:唯一值去重
unique()
函数可以帮助我们检查数据中是否有重复值,对于检测异常值非常有帮助。它返回一个包含唯一值的数组。
df["Chinese"].unique() # 获取“Chinese”列中的唯一值
如果某列中有重复值,unique()
可以帮助我们识别并处理这些重复数据。
3.5.6. query()
:按条件查询
query()
函数可以通过条件表达式来过滤数据,这对于识别某一特定范围之外的异常值非常有用。
df.query('Math > 60') # 查询 Math 列大于 60 的数据
df.query('Math > 60 and English > 60') # 多条件查询
df.query('Math in [10, 20, 30]') # 查询 Math 列为指定值的数据
query()
函数可以结合逻辑运算符(如 and
、or
)以及比较符号(如 >
, <
, ==
)对数据进行灵活的过滤。
3.5.7. sort_values()
:根据值排序
sort_values()
函数可以根据某列的值对数据进行排序,帮助我们识别最大或最小值,从而找到异常值。
df.sort_values("Chinese") # 按照“Chinese”列升序排序
df.sort_values("Chinese", ascending=False) # 降序排序
通过排序,我们可以快速发现某列的极端值,进而识别可能的异常值。
3.5.8. sort_index()
:根据索引排序
有时我们需要根据行索引来排序数据,sort_index()
函数提供了这一功能。尽管它与异常值过滤关系不大,但在数据整理过程中,它依然非常实用。
df.sort_index() # 根据索引排序
3.5.9 案例
(练习)新建一个形状为10000*3的标准正态分布的DataFrame(np.random.randn),去除掉所有满足以下情况的行:其中任一元素绝对值大于3倍标准差
df = pd.DataFrame(np.random.randn(10000, 3))
cond = df.abs() > df.std()*3 #通过矩阵的运算求得各元素是否满足条件
cond1 = cond.any(axis=1) #判断每一行是否包含一个False(即不满足条件的行)
df[~cond1] #将不满足条件的行过滤
3.5 Pandas的数学处理
3.5.1 抽样
df.take([1, 0, 3, 2])# 行排序
df.take([2, 1, 0], axis=1) #列排序
np.random.permutation([0, 1, 2]) #随机排序
# 无放回抽样
df.take(np.random.permutation([0, 1, 2]))
# 有放回抽样
df.take(np.random.randint(0, 4, size=5))
3.5.2 常用的数学函数
Pandas 提供了许多常用的数学函数,帮助我们对数据进行统计和分析
1 统计指标函数
-
max()
:计算每一列或每一行的最大值。df.max() # 默认求每一列的最大值 df.max(axis=1) # 求每一行的最大值
-
count()
:计算每一列或每一行的非空元素个数。df.count() # 默认求每一列的非空元素个数 df.count(axis=1) # 求每一行的非空元素个数
-
median()
:计算每一列的中位数。df.median() # 默认求每一列的中位数
-
mean()
:计算每一列的平均值。df.mean() # 默认求每一列的平均值
-
var()
:计算每一列的方差。df.var() # 默认求每一列的方差
-
std()
:计算每一列的标准差。df.std() # 默认求每一列的标准差
2 相关性与协方差
-
cov()
:计算每一列之间的协方差。df.cov() # 默认求每一列的协方差
-
corr()
:计算每一列之间的相关系数。df.corr() # 默认求每一列的相关系数
3 其他常用函数
-
value_counts()
:统计某一列或 Series 中每个元素的出现次数。df[0].value_counts() # 统计第0列元素的出现次数
-
cumsum()
:计算每一列的累加和。df.cumsum() # 每列的累加和
-
cumprod()
:计算每一列的累乘积。df.cumprod() # 每列的累乘积
4. 组合使用示例
假设我们有一个 DataFrame,我们可以结合上述数学函数和抽样方法进行更复杂的操作。
例如,随机抽样 3 行数据并计算它们的平均值和标准差:
import pandas as pd
import numpy as np# 示例 DataFrame
data = {'A': [1, 2, 3, 4, 5],'B': [6, 7, 8, 9, 10],'C': [11, 12, 13, 14, 15]}
df = pd.DataFrame(data)# 随机抽样
sampled_df = df.take(np.random.permutation(df.index)[:3])# 计算平均值和标准差
mean_values = sampled_df.mean()
std_values = sampled_df.std()print("抽样数据:\n", sampled_df)
print("\n平均值:\n", mean_values)
print("\n标准差:\n", std_values)
Pandans数据聚合
数据聚合通常是在数据处理的最后一步,它的目的是将每个分组的数据转换成一个单一的数值,以便做出总结或进一步分析。数据分类处理(GroupBy)是数据分析中非常重要的一步,它主要分为三个步骤:
3.6.1. 分组 (Group)
- 在分组的步骤中,数据会根据某一列或多列的值进行分组。比如,你可以根据“颜色”列将数据分为不同的颜色组,或者根据日期将数据分为不同的时间段组。
- 这一步使用
groupby()
函数来完成。groupby()
函数可以将数据框按某些列的值分组,创建一个GroupBy
对象。
grouped = ddd.groupby('color')
# 可以通过groups属性查看元素的值
grouped.groups #里面包含聚合元素的索引
3.6.2. 用函数处理 (Apply Functions)
- 一旦数据被分组,你可以对每一组数据应用特定的函数进行处理。常见的操作有求和、平均数、最大值、最小值等。
- 你可以对分组后的数据应用标准的聚合函数(如
sum()
、mean()
、count()
等),或者你可以定义自己的自定义函数来处理每个分组。
grouped_sum = grouped.sum() # 对每个分组的数据求和
grouped_mean = grouped.mean() # 对每个分组的数据求平均
也可以使用 apply()
或 agg()
方法,来应用更加复杂的操作:
grouped_custom = grouped.apply(lambda x: x['score'].max() - x['score'].min())
3.6.3. 合并 (Combine)
- 聚合操作完成后,最终的结果是各组的数据经过处理后得到的一个单一数值。
groupby()
返回的是一个GroupBy
对象,你通常需要将不同组的结果合并成一个新的数据框或系列。 - 比如,使用
sum()
或mean()
后,会返回每个分组的汇总结果,合并成一个新的数据框或系列。
final_result = grouped['score'].sum() # 对每个分组的 "score" 列求和并合并结果
groupby()
的常见方法:
- 聚合:
sum()
:求和- mean()`:均值
count()
:计数min()
:最小值max()
:最大值std()
:标准差agg()
:自定义聚合函数
- 过滤:对分组后的数据进行过滤(
filter()
) - 转换:对分组后的数据进行转换(
transform()
) - 应用:应用自定义函数(
apply()
)
3.6.4. 案例
ddd=pd.DataFrame(
data={"item":["萝卜","白菜","辣椒","冬瓜","萝卜","白菜","辣椒","冬瓜"],"color":["白","青","红","白","青","红","白","青"],"weight":[10,20,10,10,30,40,50,60],"price":[0.99,1.99,2.99, 3.99,4,5,6,7]
})
# 对ddd进行聚合操作,求出颜色为白色的价格总和
ddd.groupby("color").sum(numeric_only=False).loc['白']
# 对ddd进行聚合操作,分别求出萝卜的所有重量以及平均价格
x1 = ddd.groupby("item")[["weight"]].sum()
x2 = ddd.groupby("item")[["price"]].mean()
x1.merge(x2, left_index=True, right_index=True).loc[['萝卜']]