# 数据清洗与整(全)

# 1) 常见的数据清洗方法
# 2) 数据合并:多源数据的合并和连接
# 3) 数据重塑:针对层次化索引,学会 stack和 unstack
# 4) 字符串处理:学会 DataFrame中字符串函数的使用 # 一,常见的数据清洗方法 # 1, 查看数据基本信息
# df.info()
# df.describe()
# df.head(n): 显示数据前n行,不指定n,df.head()则会显示所有的行 # 2, 侦查缺失值
# df.isnull() :返回一个和 df结构相同的布尔型 DataFrame矩阵
# df.isnull().sum() :返回一个以 df各【列】值为nan个数为元素的序列
# df.isnull().sum().sum() :返回 df所有的 值为nan的个数和。 # df.notnull() :返回一个和 df结构相同的布尔型 DataFrame矩阵
# df.notnull().sum() :返回一个以 df各【列】值为非nan个数为元素的序列
# df.isnull().sum().sum() :返回 df所有的 值为非nan的个数和。 import numpy as np
import pandas as pd
from pandas import DataFrame,Series df=DataFrame([[3,5,np.nan],[1,3,np.nan],['tom',np.nan,'ivan'],[np.nan,'a','b']])
df
df.isnull()
df.isnull().sum()
df.isnull().sum().sum() # 4 df.notnull()
df.notnull().sum()
df.notnull().sum().sum() # 8 # 3, 删除存在缺失值的整行或整列
# 不影响原 DataFrame数据
df.dropna(how='any',axis=0) # 删除含有 NaN的整行数据 当 how='any'时,可以缺省
df.dropna(how='all',axis=0) # 删除所有值为 NaN的整行数据
df.dropna(how='any',axis=1) # 删除含有 NaN的整列数据 当 how='any'时,可以缺省
df.dropna(how='all',axis=1) # 删除所有值为 NaN的整列数据 # 4, 填充缺失值
# df.fillna? 查看函数帮助
# 当存在缺失值的行或列中的那些非缺失值很重要时,不能将整行或整列一删了之,这时需要填充缺失值: df=DataFrame([[3,5,np.nan],[1,3,np.nan],['tom',np.nan,'ivan'],[np.nan,'a','b']])
df2=DataFrame([[0,1,2,np.nan],[4,5,6,np.nan],[np.nan,np.nan,np.nan,np.nan]]) # 对所有的 NaN 填充数据:
df3=df.fillna(0,inplace=False) # 将 DataFrame中的所有 NaN填充为 0 inplace缺省时默认 inplace=False
df.fillna(0,inplace=True) # 就地修改 # 对指定的某列或某几列填充数据 -- 1 使用索引和切片调用 fillna():
df[0].fillna(df[0].mean()) # 填充第 1列,使用第一列的统计非 NaA的平均值。
df[0:2]=df[0:2].fillna('enene') # 填充第 1-3列,使用'enene'
df
df[[0,2]]=df[[0,2]].fillna('dada') # 填充第 1,3两列,使用'dada' 注意区别 df[[0,2]] 与 df[0,2]的不同,别用混了
df # 对指定的某列或某几列填充数据 -- 2 fillna()的参数传入字典:
df.fillna({0:df[0].mean()}) # 填充第 1列,使用第一列的统计非 NaA的平均值。
df2.fillna({0:0,2:'aa'}) # 给指定的列填充 第一列的填充值为 0,第 3列的填充值为 'aa'
df.fillna(method='ffifll') # df.reindex()里也有这个参数 # 对指定的某行或某几行填充数据 -- 1 使用索引和切片调用 fillna():
df.loc[0].fillna(df.loc[0].mean(),inplace=True) # 填充第 1行,使用第一行的统计非 NaA的平均值。
df.loc[0:2]=df.loc[0:2].fillna('enene') # 填充第 1-3行,使用'enene'
df
df.loc[[0,2]]=df.loc[[0,2]].fillna('dada') # 填充第 1,3两行,使用'dada'
df # 对指定的某行或某几行填充数据 -- 2 fillna()的参数传入字典:(不推荐)
# 给行填充不能使用字典参数加 axis=1的方式,会报错的,但可以使用转置的方法转成列再填充,然后转置回来。
df=df.T.fillna({2:'aa'}).T
df=df.T.fillna({0:0,3:'aa'}).T # 给指定的行填充 转置两次 # 5, 移除重复数据
# 移除行数据完全相同的行:
df.duplicates() # 返回一个布尔型序列 True表示与前面行数据有重复
df.drop_duplicates() # 保留第一次出现的行数据,删除其他的重复行数据 keep='first' 可缺省
df.drop_duplicates(keep='last') # 保留最后一次出现的行数据,删除其他的重复行数据 # 移除以指定列所谓判断重复标准的的行:
df.drop_duplicates(subset=['sex','year'],keep='last') # 以指定的'sex','year'列作为判断依据。 # 6, 替换值:df.replace()
df.replace('','未知') # 将 df中所有的 ""替换为 "未知"
df.replace(['',2001],['未知',2002]) # 将 df中所有的 ""替换为 "未知",将 2001替换为 2002
df.replace({'':'未知',2001:2002}) # 将 df中所有的 ""替换为 "未知",将 2001替换为 2002 # 7, 利用函数或映射进行数据转换
# 判断分数等级:90-100 优秀; 70-89 良好; 60-69 及格; <60 不及格
# python可以使用 循环加 if 判断来解决
# pandas 可以使用 自定义函数+map()函数来实现 data={
'name':['张三','李四','王五','马六'],
'grade':[75,52,63,99]
} df=DataFrame(data) def f(x):
if x>=90:
return '优秀'
elif 70<=x<90:
return '良好'
elif 60<=x<70:
return '合格'
else:
return '不合格' df['class']=df.grade.map(f) # df['class']=df['grade'].map(f)
df # 8, 检测异常值
df=DataFrame(np.arange(10),columns=['X'])
df['Y']=df['X']*2+0.5
df.iloc[9,1]=185 # 将第 9行第 1列的值由 18.5改为 185
df.plot(kind='scatter',x='X',y='Y') # 9, 虚拟变量(暂时用不到,数学建模机器学习)
# 对于单类别的数据:使用 pd.get_dummies()
df = DataFrame(
{
'朝向':['东','南','东','西','北']
'价格':[1200,2000,1200,1100,800]
}
)
df
pd.get_dummies(df['朝向']) # 对于多类别的数据:使用 apply()
df = DataFrame(
{
'朝向':['东/北','南/西','东','西/北','北']
'价格':[1200,2000,1200,1100,800]
}
)
df
dummies=df['朝向'].apply(lambda x:Series(x.split('/')).value_counts())
dummies # 二,数据合并与重塑
# 当要数据来源于多处时,就需要对数据进行合并和重塑。 # 1, pd.merge(df1,df2,on='fruit',how='inner'...)函数: # how--how='inner' 内连接,交集(默认)
# how='outer' 外连接,并集
# how='left'左连接 以 df1为主表,右表没数据为 NaN
# how='right'右连接 以 df2为主表,右表没数据为 NaN # left--指参数列表里第一个 Daframe
# right--指参数列表里第二个 Daframe
# on--用于连接的列名
# left_on--df1用于连接的列名 与 right_on--df2用于连接的列名 成对出现
# left_index--df1的行索引作为连接键 因为行索引也可以看作是一列
# right_index--df2的行索引作为连接键
# sort--合并后对数据进行排序,默认为True
# suffixes--修改重复名 # 通过一个键或多个键(DataFrame的列)将两个DataFrame按行合并起来,类似于SQL。
price=DataFrame(
{
'fruit':['apple','banana','orange'],
'price':[23,32,45]
}
) amount=DataFrame(
{
'fruit':['apple','banana','apple','apple','banana','pear'],
'amount':[5,3,6,3,5,7]
}
) pd.merge(amount,price,on='fruit') # 交集
pd.merge(amount,price,on='fruit',how='outer') # 并集
pd.merge(amount,price,on='fruit',how='left') # 左连接 # 多对多的连接,笛卡尔积:
# 只使用一个键来连接时,price2里有2个 apple,amount2里有3个apple,连接的结果就有6个apple. price2=DataFrame(
{
'fruit':['apple','banana','orange','apple'],
'price':[23,32,45,25]
}
) amount2=DataFrame(
{
'fruit':['apple','banana','apple','apple','banana','pear'],
'amount':[5,3,6,3,5,7]
}
) pd.merge(amount2,price2,on='fruit',how='outer') # 并集 # 多个键合并,使用列表:
df1=DataFrame(
{
'k1':['one','one','two'],
'k2':['a','b','a'],
'v1':[2,3,4]
}
) df2=DataFrame(
{
'k1':['one','one','two','two'],
'k2':['a','a','a','b'],
'v1':[5,6,7,8]
}
) # pd.merge(df1,df2,on='k1',how='outer') # 当只指定一个连接键的时候,容易出现笛卡尔积
pd.merge(df1,df2,on=['k1','k2'],how='outer') # 用两个连接键作为约束,就可以避免不必要的笛卡尔积 # suffixes 处理重复列名的问题:
pd.merge(df1,df2,on='k1',how='outer',suffixes=('_left','_right')) # suffixes 处理重复列名的问题 # 使用行索引作为连接键来使用:right_index=True 或 left_index=True
df1=DataFrame(
{
'k':['a','b','a'],
'v1':[2,3,4]
}
) df2=DataFrame({'v2':[5,6,7,8]}index=['a','b'])
pd.merge(df1,df2,left_on='key',right_index=True) # 将两个Dataframe同时按照索引连接起来:
# 1)方法一,使用 merge:
pd.merge(df1,df2,left_on='k',left_index=True,right_index=True,how='outer')
# 2)方法二,使用 join:
df1.join(df2,how='outer') # 2, pd.concat([s1,s2],axis=0,join='outer',join_axes=[['b','a']]) # 默认 axis=0 默认 join='outer' join只有 inner和 outer两个值可选. join_axes用来指定索引顺序
# 当要合并的两个 DataFrame没有连接键时,不能使用 merge,可以使用 contact。
# concat只会连接不会去重。想要对结果去重,得使用 df.drop_duplicates()。 # 对于 Series:
s1=Series([0,1],index=['a','b'])
s2=Series([0,3],index=['a','d']) # a标签与 s1重复
s3=Series([4,5],index=['e','f']) pd.concat([s1,s2,s3]) # 共 6行 1列 axis=0
pd.concat([s1,s2,s3],axis=1) # 共 5行 3列 axis=1
pd.concat([s1,s2],axis=1,join='outer') # join='outer' 并集 2列 3行 a b d
pd.concat([s1,s2],axis=0,join='outer') # join='outer' 并集 1列 4行 a b a d 默认
pd.concat([s1,s2],axis=1,join='inner') # join='inner' 交集 2列 1行 a
pd.concat([s1,s2],axis=0,join='inner') # join='inner' 交集 1列 4行 a并集 默认 # 如果想在结果中很容易区分出参与连接的对象,可以使用 keys参数给连接对象创建一个层次化索引。
pd.concat([s1,s2],axis=0,join='inner',keys=['first','second'])
pd.concat({'first':s1,'second':s2},axis=0,join='inner') pd.concat([s1,s2],axis=1,join='inner',keys=['first','second'])
pd.concat({'first':s1,'second':s2},axis=1,join='inner') # 对于 DataFrame:
price=DataFrame(
{
'fruit':['apple','banana','orange'],
'price':[23,32,45]
}
) amount=DataFrame(
{
'fruit':['apple','banana','apple','apple','banana','pear'],
'amount':[5,3,6,3,5,7]
}
) pd.concat([price,amount],axis=1) # 重新生成默认索引:对于 axis=0时有用
price=DataFrame(
{
'fruit':['apple','banana','orange'],
'price':[23,32,45]
},index=['a','b','c']
) amount=DataFrame(
{
'fruit':['apple','banana','apple','apple','banana','pear'],
'amount':[5,3,6,3,5,7]
},index=['a','b','c','d','e','f']
) pd.concat([price,amount],axis=0)
pd.concat([price,amount],axis=0,ignore_index=True) # 不会改变数据结构,只是生成新的默认索引 # 3, combine_first()合并
# combine_first()使用的连接键是行索引(行索引可以看作为一个列)
# 如果需要合并的两个 DataFrame存在重复的索引,在这种情况下,若使用 merge和 concat方法都不能准确的解决问题,此时需要
# combine_first方法,类似于打补丁,以调用的 DataFrame为主,参数里的 DataFrame作为补丁。
price=DataFrame(
{
'fruit':['apple','banana',np.nan,'pear'],
'price':[23,32,np.nan,np.nan]
},index=['a','b','c','d']
) amount=DataFrame(
{
'fruit':['apple','banana','apple','apple','banana','pear'],
'price':[5,3,6,3,5,7],
'amount':[1,1,1,1,1,1]
},index=['a','b','c','d','e','f']
) price.combine_first(amount) # 4, 数据重塑 stack 堆叠
# 1) df.stack()方法: 将每个行索引对应的列索引堆叠起来形成内层行索引变成层次化索引的序列 Series
# 2) df.unstack()方法: df.stack()的反操作。 df=DataFrame(np.arange(9).reshape(3,3),index=['a','b','c'],columns=['one','two','three'])
df.index.name='alph'
df.columns.name='number' Se=df.stack() # 其结果是一个层次化的序列
type(Se) # pandas.core.series.Series
Se.unstack(),Se.unstack(1),Se.unstack('number')
# unstack() 可以指定参数,默认是 Se的内层索引的名字(即原 DataFrame df1的columns.name)或表示层次结构的数字 1
# 如果将参数指定为 0或 Se的外层索引的名字(即原 DataFrame df1的index.name),则得到 df1的转置。
Se.unstack(0),Se.unstack('alph') # 对于本身就是层次化索引的 DataFrame,其 stack()和 unstack()用到再说吧。 # 三, 字符串处理 # 1) Python 内建字符串方法:
# str.count() 返回字符串在字符串中的非重叠出现的次数
# str.endwith() 如果字符串以后缀结尾则返回 True
# str.startwith() 如果字符串以后缀结尾则返回 True
# str.join() 使用字符串作为间隔,用于黏合其他字符串的序列
# str.index() 如果在字符串中找到,则返回字符串的第一个字符的位置,如果找不到,则引发 ValueError
# str.find() 类似于 str.index(),只是找不到时返回 -1.
# str.rfind() 返回目标字符串在字符串中最后出现的位置,找不到则返回 -1.
# str.replace() 使用一个字符串替代另一个字符串
# str.strip(),str.rstrip().str.lstrip() 修剪空白,包括换行符;
# str.split() 使用分隔符将字符串拆分为子字符串的列表
# str.lower() 将大写字母转换为小写字母
# str.upper() 将小写字母转换为大写字母
# str.casefold() 将字符串转换为小写,并将任何特定于区域的变量字符串组合转换为常见的可比较的形式
# str.ljust(),str.rjust() 左对齐或右对齐;用空格(或其他一些字符)填充字符串的相反侧以返回具有最小宽度的字符串。 # 2) pandas 处理字符串数据的矢量化函数:
# https://blog.csdn.net/dta0502/article/details/81839048
# 向量化字符串方法:
# se.str.cat() 根据可选的分隔符,按元素黏合字符串
# se.str.contains() 返回是否含有某个模式/正则表达式的布尔值数组
# se.str.count() 模式出现次数的计算
# se.str.extract() 使用正则表达式从字符串 Series中分组抽取一个或多个字符串;返回的结果是每个分组形成一列的 DataFrame
# se.str.endswith() 等价于每个元素使用 x.endwith(模式)
# se.str.startswith() 等价于每个元素使用 x.startswith(模式)
# se.str.match() 使用 re.match()将正则表达式应用到每个元素上,将匹配分组以列表的形式返回。
# se.str.findall() 找出字符串中所有的模式/正则表达式匹配项,以列表返回。
# se.str.get() 对每个元素进行索引 (获取第 i 个元素)
# se.str.isalnum() 等价于内建的 str.alnum()
# se.str.isalhpa() 等价于内建的 str.isalhpa()
# se.str.isdecimal() 等价于内建的 str.isdecimal()
# se.str.isdigt() 等价于内建的 str.isdigt()
# se.str.islower() 等价于内建的 str.islower()
# se.str.isupper() 等价于内建的 str.isupper()
# se.str.isnumeric() 等价于内建的 str.isnumeric()
# se.str.join() 根据传递的分隔符,将 Series中的字符串联合
# se.str.len() 计算每个字符串的长度
# se.str.lower/se.str.upper() 对每个元素进行 大小写转换
# se.str.repeat() 重复值(如, se.str.repeat(3))
# se.str.replace() 以其他字符串替代模式/正则表达式的匹配项
# se.str.slice() 对 series中的字符串进行切片
# se.str.split() 以分隔符或正则表达式对字符串进行拆分
# se.str.strip() 对字符串的两侧的空白进行消除,包括换行符。
# se.str.rtrip() 对字符串的右侧的空白进行消除。
# se.str.ltrip() 对字符串的左侧的空白进行消除。
# se.str.pad() 将空白加到字符串的 左边,右边,或者两边
# se.str.center() 等价于 pad(side='both') # 1, 字符串方法:以 str.split() 为例:
# 示例,将一列字符串数据分成两列:
data={
'data':['张三|男','李四|女','王五|女','马六|男']
} df=DataFrame(data) # 传统方法 1:
df['name']=df['data'].apply(lambda x:x.split("|")[0])
df['gender']=df['data'].apply(lambda x:x.split("|")[1])
del df['data']
# df=df[['name','gender']] # 重新排列列的顺序
df # 传统方法 2:
df=df['data'].apply(lambda x:Series(x.split("|"))) #
df.columns=['name','gender'] # 发现结果里没有了列名,重新按位置定义列名
# df.rename(columns={'data':'name'}, inplace = True) # 重命名列
df # pandas 方法:
# pandas中字段的 str属性可以轻松调用字符串的方法,并矢量化到整个字段数据中:
# df['data'].str.split("|") # dataframe 的 data字段的 str属性 调用了 split()方法 返回一个以列表为元素的序列 data={
'data':['张三|男','李四|女','王五|女','马六|男']
} df=DataFrame(data)
se=df['data'].str.split("|") # type(se) # pandas.core.series.Series
df['name']=se.str[0]
df['gender']=se.str[1]
del df['data']
df # 2,正则表达式: # re模块中 常用的正则表达式方法:(注意不是 pandas可用的)
# 1)findall 将字符串中的所有非重叠匹配模式以列表形式返回。
# 2)finditer 与 findall 类似,只是返回的是 迭代器
# 3)match 在字符串起始位置匹配模式,也可以将模式组件匹配到分组中;如果模式匹配上了,返回match_object对象,否则返回 None
# 4) search,split,sub,subn等详见 正则表达式那个总结。 # 字符串的矢量化操作同样适用于正则表达式:
df=DataFrame({
'email':['100@qq.com','111@qq.com','222@qq.com']
}) se=df['email'].str.findall('(.*?)@')
type(se) # pandas.core.series.Series
df['qq']=df['email'].str.findall('(.*?)@').str.get(0)
df
import pandas as pd
from pandas import DataFrame
df=DataFrame({
'email':['100@qq.com','111@qq.com','222@qq.com']
}) # se=df['email'].str.findall('(.*?)@')
# type(se) # pandas.core.series.Series
# df['qq']=se.str.get(0) # get()是对每一个元素进行索引。
# df
df['qq']=df['email'].str.findall('(.*?)@').str.get(0) # 注,没有 str.search()方法。
df
.dataframe tbody tr th:only-of-type { vertical-align: middle }
{ vertical-align: top }
.dataframe thead th { text-align: right }

email qq
0 100@qq.com 100
1 111@qq.com 111
2 222@qq.com 222

Pandas_数据清洗与整理_全的更多相关文章

  1. phpcms标签整理_当前栏目调用

    phpcms标签整理_当前栏目调用 转载 **//SQL语句调用: {pc:get sql="select * from phpcms_category where catid in($ca ...

  2. R语言扩展包dplyr——数据清洗和整理

    R语言扩展包dplyr——数据清洗和整理 标签: 数据R语言数据清洗数据整理 2015-01-22 18:04 7357人阅读 评论(0) 收藏 举报  分类: R Programming(11)  ...

  3. Flutter实战视频-移动电商-60.购物车_全选按钮的交互效果制作

    60.购物车_全选按钮的交互效果制作 主要做全选和复选框的这两个功能 provide/cart.dart 业务逻辑写到provide里面 先持久化取出来字符串,把字符串编程list.循环list ca ...

  4. 大牛整理最全Python零基础入门学习资料

    大牛整理最全Python零基础入门学习资料 发布时间:『 2017-11-12 11:56 』     帖子类别:『人工智能』  阅读次数:3504 (本文『大牛整理最全Python零基础入门学习资料 ...

  5. Pandas_基础_全

    Pandas基础(全) 引言 Pandas是基于Numpy的库,但功能更加强大,Numpy专注于数值型数据的操作,而Pandas对数值型,字符串型等多种格式的表格数据都有很好的支持. 关于Numpy的 ...

  6. python基础全部知识点整理,超级全(20万字+)

    目录 Python编程语言简介 https://www.cnblogs.com/hany-postq473111315/p/12256134.html Python环境搭建及中文编码 https:// ...

  7. 前端CSS规范整理_转载、、、

    一.文件规范 1.文件均归档至约定的目录中. 具体要求通过豆瓣的CSS规范进行讲解: 所有的CSS分为两大类:通用类和业务类.通用的CSS文件,放在如下目录中: 基本样式库 /css/core 通用U ...

  8. java_eclipse_maven_svn_主题彩色插件_全屏插件

    作为一名不算新手的猿猿,还来纠结IDE环境搭建实属不该,不过着实纠结了不少时间. target: eclipse + maven +svn + 设置默认编码+全屏 绕的路就不说了,直奔主题,由于mav ...

  9. PHP学习过程_Symfony_(3)_整理_十分钟学会Symfony

    这篇文章主要介绍了Symfony学习十分钟入门教程,详细介绍了Symfony的安装配置,项目初始化,建立Bundle,设计实体,添加约束,增删改查等基本操作技巧,需要的朋友可以参考下 (此文章已被多人 ...

随机推荐

  1. git 上传文件到 gitee 码云远程仓库(强制上传)

    1.先git init 会出现一个.git的文件夹,有些人可能是隐藏了,工具哪里打开就行了 2.将当前的数据上传到码云,看清楚奥,是当前.git add ./ 这是代表当前的意思 3.将上传的数据备注 ...

  2. HanLP的分词统计

    HanLP的分词效果鄙人研究了HanLP,他的分词效果确实还可以,而且速度也比较快,10的数据是9000毫秒 @SneakyThrows@Overridepublic LinkedHashMap< ...

  3. RxJS入门2之Rxjs的安装

    RxJS V6.0+ 安装 RxJS 的 import 路径有以下 5 种: 1.创建 Observable 的方法.types.schedulers 和一些工具方法 import { Observa ...

  4. js、css等文件引入空白问题

    路径没错,不管路径怎么改变,js.css等文件就是引入失败.很多时候是因为Spring的过滤器把js.css等资源文件拦截了.default是tomcat配置的一个servlet,"Defa ...

  5. 分布式系统中的CAP、ACID、BASE概念

    目录 CAP ACID BASE CAP 分布式系统中,这三个特性只能满足其中两个. 一致性(Consistency):分布式中一致性又分强一致性和弱一致性,强一致性主浊任何时刻任何节点看到的数据都是 ...

  6. 搭建分布式 Redis Cluster 集群与 Redis 入门

    目录 Redis 集群搭建 Redis 是啥 集群(Cluster) Redis Cluster 说明 Redis Cluster 节点 Redis Cluster 集群模式 不能保证一致性 创建和使 ...

  7. 第七章 TCP和UDP原理

    一.引入 1.TCP/IP协议族的传输层协议主要包括TCP和UDP 2.TCP是面向连接的可靠的传输层协议.它支持在并不可靠的网络上实现面向连接的可靠的数据传输 3.UDP是无连接的传输协议,主要用于 ...

  8. Linux系统安装MySQL(2020最新最详细)

    2020最新Linux系统发行版ContOS7演示安装MySQL. 为防止操作权限不足,建议切换root用户,当然如果你对Linux命令熟悉,能够自主完成权限更新操作,可以不考虑此推荐. 更多命令学习 ...

  9. 为啥 Response.Write 后,View就不渲染了?

    一:背景 1. 讲故事 前几天群里有一位朋友聊到,为什么我在 Action 中执行一句 Response.Write 之后,后续的 View 就不呈现了,如果脑子中没有画面,那就上测试代码: publ ...

  10. MySQL数据库基础-3-SQL 基本概念

    SQL 基本概念 约束:constraint,表中的数据要遵守的限制 主键:一个或多个字段的组合,填入的数据必须能在本表中唯一标识本行:必须提供数据,即NOT NULL,一个表只能有一个 惟一键:一个 ...