【玩转pandas系列】数据清洗(文末送书)

文章目录

  • 一、重复值检测
  • 二、元素替换
    • 1️⃣ 元素替换replace
    • 2️⃣ 数据映射map
  • 三、修改索引
    • 1️⃣ 修改索引名rename
    • 2️⃣ 设置索引和重置索引
  • 四、数据处理
    • 1️⃣ apply与applymap
    • 2️⃣ transform
  • 五、异常值处理
  • 六、抽样聚合函数
    • 1️⃣ 抽样
    • 2️⃣ 数学函数
  • 七、分组聚合
  • 🎁 文末福利

本文介绍在数据分析中如何使用 pandas 进行数据清洗,是 pandas 学习阶段的 重点,没有之一。

一、重复值检测

pandas中用于重复值检测的是 duplicated() 函数,可以用于检测行或列是否前后重复,返回值是 bool 类型。True 表示重复,False 表示不重复。

函数参数:

  • keep:默认情况下 keep = first ,表示第一行不重复,后面的行参照第一行,取值还有 last(认为最后一行不重复),False(标记所有重复行)。

  • subset:只检测某些列是否重复,值是一个列表。

首先导入必要的包,并定义一个用于构建 dataframe 对象的函数:

import numpy as np
import pandas as pd
# 定义生成 dataframe 对象的函数
def make_df(indexs,columns):
    data = [[str(j)+str(i) for j in columns] for i in indexs]
    df = pd.DataFrame(data=data,index=indexs,columns=columns)
    return df
df = make_df(list('123'),list('ABC'))
df

下面演示 duplicated() 函数以及参数的使用:

# 让第一行和第二行一样
df.loc['1'] = df.loc['2']
df

df.duplicated()


等价写法:

df.duplicated(keep='first')

以最后一行为不重复参照:

df.duplicated(keep='last')


标记所有重复行:

df.duplicated(keep=False)


只检查 B、C 列:

df.duplicated(subset=['B','C'])

二、元素替换

1️⃣ 元素替换replace

replace 函数用于替换单个的元素。

首先构建 dataframe 对象:(本文后面用到的 dataframe 对象都是这个,只是数据是随机产生的,和我的肯定不同,但是不重要)

index = ['张三','张三丰','李白','杜甫']
columns = ['Python','Java','H5','UI']
data = np.random.randint(0,100,(4,4))
df = pd.DataFrame(data=data,index=index,columns=columns)
df


将1、11分别改为60,61:

df.replace({1:60,11:61})

2️⃣ 数据映射map

map 一般用于 Series 结构,不能用于 dataframe ,因此,我们在使用 map 来处理 dataframe 对象时,应该取一个 Series (列)。

如果对 dataframe 对象使用 map 函数(不是下面的第一种情况):

df.map(lambda x:'及格' if x >= 60 else '不及格')


如果对 Series 对象使用 map 函数(下面的2、3种情况):

df['Python'].map(lambda x:'及格' if x >= 60 else '不及格')

  • 1.直接使用 map

现在将上面的4、18分别改为44,81:

df.map({4:44,18:81})

  • 2.使用 lambda 表达式

现在使用 lambda 表达式筛选 Python 成绩,分为及格和不及格。

df['Python'].map(lambda x:'及格' if x >= 60 else '不及格')
  • 3.使用普通函数

使用普通函数,即为 map 函数传递一个函数名:

# 使用普通函数
def fn(x):
    if x >= 60:
        return '及格'
    return '不及格'
df['UI'].map(fn)

三、修改索引

1️⃣ 修改索引名rename

使用 pd.rename() 函数可以修改索引,默认是修改行索引,传递字典。

使用 rename 函数修改行索引:

df.rename({'张三':'ZhangSan'})

如果要修改列索引,要使用 axis = 1 指定:

df.rename({'Python':'派森'},axis=1)

或者使用 columns 参数:

df.rename(columns={'Java':'爪哇'})

结果如下:

修改行索引还是修改列索引,可以通过 axis 控制,也可以使用 index 、 columns 参数控制。

2️⃣ 设置索引和重置索引

pandas中 set_index() 函数用于将 keys 参数中指定的列索引变为行索引。

接下来使用 set_index() 修改列索引 Python 为行索引:

df.set_index(keys=['Python'])

函数参数:

  • keys:列表类型,用于指定要更改的列。

  • drop:bool 类型,默认为True,表示列改为行索引后,删除原来的列。

  • append:bool 列行,默认为False,表示不追加,删除原来的行索引。

重置行索引使用 reset_index 函数,重置列索引使用的是 df.columns 重新赋值。

分别重置行索引和列索引:

df.columns = ['1','2','3','4'] 
df

四、数据处理

apply、applymap、transform 都是用于数据处理的函数,其中 applymap 只适用于处理 dataframe ,apply 和 transform 适用于处理 Series 和 DataFrame 。

1️⃣ apply与applymap

apply 应用于Series:

df['Python'].apply(lambda x: True if x > 60 else False)

apply 应用于DataFrame(求每一列的平均值):

df.apply(lambda x:x.mean())


也可以传递一个函数,并控制计算行或列:

def fn(x):
    return (x.mean(),x.count())
df.apply(fn,axis=1)


applymap 处理 dataframe :

# 处理Series报错
df['Python'].applymap(lambda x:x*10)

# 处理dataframe不报错
df.applymap(lambda x:x*10)

2️⃣ transform

transform 处理 Series(计算Python列的平方根):

df['Python'].transform(np.sort)

transform 处理 DataFrame(平均值大于6就除以6):

def fn(x):
    if x.mean() > 6:
        return x / 6
    return x
df.transform(fn)

五、异常值处理

这部分的内容,主要介绍8个常用函数的用法,为了防止图片过多,部分实际运行结果已省略。

  • describe()

describe函数用于查看 dataframe 对象的列数,平均值,标准差,最小值、最大值、平均值等。

# 构建dataframe对象
data = np.random.randint(0,10,(5,3))
df = pd.DataFrame(columns=['NumPy','Pandas','Pytorch'],data=data)
df

df.describe()


查看更细致的百分位数,并且转置:

df.describe([0.01,0.33,0.99]).T

  • info()、std()

info 函数用于查看数据类型、行列索引、每一列数据非空情况、类型、内存使用情况等。
std() 函数用于求每一列的标准差。

df.info()
df.std()
  • drop()

drop 函数用于删除索引。可以通过 axis 或者 index / columns 控制删除行索引还是列索引。

df2.drop(0) # 默认删除行
df2.drop(index=0) # 等价写法
df2.drop('NumPy',axis=1) # 删除列
df2.drop(columns='NumPy') # 等价写法
df2.drop(columns=['NumPy','Pandas']) # 删除多列
df2.drop(columns='NumPy',inplace=True) # 修改原数据
  • unique()

unique 函数用于去重,只能应用于 Series 对象,不能用于 DataFrame 对象。

df['Pytorch'].unique()
  • query()

query 函数用于查询特定的行。

df.query('Pandas == 6') # 查询pandas = 6的行
df.query('Pytorch > 2') # 查询Pytorch > 2的行
df.query('Pandas == 6 and Pytorch > 2' ) # 使用 and 符
n = 3
df.query('Pytorch > @n') # 使用变量
  • sort_values()

sort_values 函数作用是根据值对行或列进行排序。

df.sort_values('Pandas') # 默认列排序
df.sort_values('Pandas',ascending=False) # 降序
df.sort_values(0,axis=1) # 行排序
  • sort_index()

sort_index 函数用于对索引排序,数字按大小,非数字按 ASCII 码。

df.sort_index() # 默认对行索引排序(axis = 0),并且是升序(ascending = True)
df.sort_index(ascending=False) # 降序
df.sort_index(axis = 1,ascending=False) # 对列索引排序,并且降序

六、抽样聚合函数

1️⃣ 抽样

pandas 中有两种抽样,分别是有放回抽样(可能重复)和无放回抽样(不会重复),使用 take 函数抽取,下面使用代码表示。

首先查看 dataframe 对象:

  • 无放回抽样
df.take([0,2,3,1,4]) # 交换行

运行结果分别是:

df.take([0,2,1],axis=1) # 交换列

df.take(np.random.permutation([0,1,2,3,4])) # 随机交换

  • 有放回抽样
df.take(np.random.randint(0,4,size=5))

2️⃣ 数学函数

这里罗列出了一些常用的数学函数,不再以代码演示。

函数名功能
count非空值数量
max / min最大 / 小值
median / mean中位数 / 平均数
sum
value_counts元素出现次数
cumsum累加
cumprod累乘
std标准差
var方差
cov协方差
corr相关系数

七、分组聚合

分组操作通过 groupby() 方法实现,得到的是一个 DataFrameGroupBy 对象,该对象与 DataFrame 类似,操作和 DataFrame 一样即可。

下面结合例题讲解 groupby 方法。

有如下 dataframe 对象:

df = pd.DataFrame(
    data={
        'item':['萝卜','白菜','辣椒','冬瓜','白菜','辣椒','萝卜','萝卜'],
        'color':['白色','青色','红色','白色','白色','青色','红色','青色'],
        'weight':[1,0,3,4,5,2,12,3],
        'price':[0.99,1.5,2,5,4,2,9,2]
    }
)
df

  • 1.求出颜色为白色的价格总和
# 要得到颜色为白色的所有行,首先要按照颜色进行分组,通过 by 参数指定
df.groupby(by='color')
# 接下来取出价格列(Series类型)
df.groupby(by='color')['price']
# 进行求和
df.groupby(by='color')['price'].sum()
# 最后取出白色
df.groupby(by='color')['price'].sum()['白色']
  • 2.分别求出萝卜的总重量和平均价格
# (1)
# 首先按照item分类
df.groupby('item')
# 然后取出重量
df.groupby('item')['weight']
# 求和
df.groupby('item')['weight'].sum()
# 再取出萝卜
df.groupby('item')['weight'].sum()['萝卜']
#(2)
# 类似的,得到平均价格
df.groupby('item')['price'].mean()['萝卜']
  • 3.使用 merge 合并总重量和平均价格

因为上述取出 weightprice 后是 Series 对象,我们要稍作改变为 DataFrame 对象,才能使用 merge 进行合并。

df1 = df.groupby('item')[['weight']].sum()
df2 = df.groupby('item')[['price']].mean()
display(df1,df2)


# 因为两个 df 对象没有相同列,合并时要使用 left / right_index
df1.merge(df2,left_index=True,right_index=True)

🎁 文末福利

本期送出《Python机器学习:基于PyTorch和Scikit-Learn》。

本书是一本全面介绍在PyTorch环境下学习机器学习和深度学习的综合指南,可以作为初学者的入门教程,也可以作为读者开发机器学习项目时的参考书。

本书讲解清晰、示例生动,深入介绍了机器学习方法的基础知识,不仅提供了构建机器学习模型的说明,而且提供了构建机器学习模型和解决实际问题的基本准则。本书添加了基于PyTorch的深度学习内容,介绍了新版Scikit-Learn。本书涵盖了多种用于文本和图像分类的机器学习与深度学习方法,介绍了用于生成新数据的生成对抗网络(GAN)和用于训练智能体的强化学习。最后,本书还介绍了深度学习的新动态,包括图神经网络和用于自然语言处理(NLP)的大型transformer。无论是机器学习入门新手,还是计划跟踪机器学习进展的研发人员,都可以将本书作为使用Python进行机器学习的不二之选。

学完本书,你将能够:

  • 探索机器从数据中“学习”的框架、模型和方法。

  • 使用Scikit-Learn实现机器学习,使用PyTorch实现深度学习。

  • 训练机器学习分类器分类图像、文本等数据。

  • 构建和训练神经网络、transformer及图神经网络。

  • 探索评估和优化模型的最佳方法。

  • 使用回归分析预测连续目标结果。

  • 使用情感分析深入地挖掘文本和社交媒体数据。

✳️ 点这里去往:购买链接

🎁 本次送书1~5本【阅读量越多,送的越多】

⌛️ 活动时间:截止到2023-08-8 10:00

✳️ 参与方式: 关注博主+三连(点赞、收藏、评论)(切记要点赞+收藏,否则抽奖无效)

🏆 抽奖方式: 评论区随机抽取小伙伴免费送出!!

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2023年8月3日
下一篇 2023年8月3日

相关推荐