数据分析学习笔记之数据预处理

数据加载

我们首先需要将手机到的数据加载到内存中,才能进行进一步的操作。pandas提供了非常多的读取数据的函数,分别应用在各种数据源环境中,我们常用的函数为:

  • read_csv
  • read_table
  • read_sql
    注意:
    read_csv与read_table功能相同,只不过默认使用的分隔符不同。read_csv默认使用的分隔符为逗号,而read_table默认使用的分隔符为制表符(\t)。分隔符可以通过参数sep或delimiter来指定。

常用参数:
read_csv与read_table常用的参数如下

  • sep/delimiter
  • header
  • names
  • index_col
  • usecols
    1.默认情况下,会讲读取到数据的首行作为标题。如果我们不需要首行作为标题,那么我们可以通过header参数来设置。
    斜体样式这里我们使用的数据集名为spider.csv。
import numpy as np
import pandas as pd
df = read_csv("spider.csv")
df.head(10) # 显示数据的前十行

结果如下:
在这里插入图片描述
我们可以看到,第一行的数据充当了标题。我们可以通过设置header=None来将数据正常显示。

df = pd.read_csv("spider.csv",header=None)
df.head(10)

我们可以看到,标题已经被数字索引代替了。
在这里插入图片描述
2.我们可以在读取之后,通过columns设置列标签(标题)。但是,我们也可以通过names参数来指定。

# df.columns[""]
df = pd.read_csv("spider.csv", header=None, names=["date", "url", "infor", "value1", "value2"])
df.head(3)

效果如下,我们修改了数据集的列标签。
在这里插入图片描述
3.当数据表中的某一列(某几列)可以作为唯一标记,我们就不用再去生成单独的行索引(行标签)。通过index_col来指定列。

df = pd.read_csv("spider.csv", header=None, names=["date", "url", "infor", "value1", "value2"], index_col="date")
df.head(3)

结果如下,我们成功的使用了date列作为行标签。
在这里插入图片描述
4.当我们读取数据集时,数据集中可能存在很多列,但是,并非每一列都是我们想要的(感兴趣的)。我们可以通过usecols参数来显示指定需要加载哪些列。(默认为所有列)

df = pd.read_csv("spider.csv", header=None, names=["date", "url", "infor", "value1", "value2"], usecols=["date", "url"]
df.head(3)

指定显示的列为date和url,结果如下。
在这里插入图片描述
从数据库中读取数据
sqlite3连接参数指定的数据库。如果数据库不存在,则会创建该数据库,然后再进行连接。
存在则直接进行连接。该方法返回数据库的连接。通过数据库连接对象的execute方法执行sql语句。

import sqlite3
con = sqlite3.connect("test.db")//如果不存在,则创建相关db文件。
con.execute("create table person(id varchar(32) primary key, name varchar(100) )") //创建表
# 向数据表中插入数据记录
con.execute("insert into person(id, name) values('1', 'bill')")
con.execute("insert into person(id, name) values('2', 'li')")
con.commit() // 提交之前的操作

# 从数据中指定的sql中,读取数据。需要指定一个数据库的连接对象。
pd.read_sql("select id, name from person", con)

写入文件

DataFrame与Series对象的to_csv方法:

  • to_csv

该方法可以将数据写入:

  • 文件中
  • 数据流中

常用参数

  • sep
  • header 是否写入标题行
  • na_rep 空值的表示
  • index 是否写入索引
  • index_label 索引字段的名称
  • columns 写入的字段

数据清洗

我们需要对数据进行一些预处理操作,才能用到后续的数据分析与机器学习中。这是因为,无论数据的来源为何处,我们都不可能保证数据一定是准确无误的。
数据清洗可以包含以下几方面内容:

  • 处理缺失值
  • 处理异常值
  • 处理重复值

缺失值处理
1.发现缺失值
Pandas中,会将float类型的nan与None视为缺失值,我们可以通过如下方法来检测缺失值:

  • info
  • isnull
  • notnull
    说明:
    判断是否存在空值,可以将isnull与any或all结合使用。
    2.丢弃缺失值
    对于缺失值,我们可以将其进行丢弃处理(dropna)。
    说明:
  • how:指定dropna丢弃缺失值的行为,默认为any。
  • axis:指定丢弃行或者丢弃列(默认为丢弃行)。
  • thresh:当非空数值达到该值时,保留数据,否则删除。
  • inplace:指定是否就地修改,默认为False。
  • subset:删除空值时,其他轴方向考虑的标签子集。

3.填充缺失值
我们也可以对缺失值进行填充(fillna)。
说明:

  • value:填充所使用的值。可以是一个字典,这样就可以为DataFrame的不同列指定不同的填充值。
  • method:指定前值(上一个有效值)填充(pad / ffill),还是后值(下一个有效值)填充(backfill / bfill)。
  • limit:如果指定method,表示最大连续NaN的填充数量,如果没有指定method,则表示最大的NaN填充数量。
  • inplace:指定是否就地修改,默认为False。

我们同样的使用spider.csv作为例子,来验证一下相关属性。

  • 发现缺失值

info

df = pd.read_csv("spider.csv",header=None)
df.info()

结果如下:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1396 entries, 0 to 1395
Data columns (total 5 columns):
0    1396 non-null object
1    1396 non-null object
2    1396 non-null object
3    1098 non-null float64
4    1098 non-null float64
dtypes: float64(2), object(3)
memory usage: 54.7+ KB

isnull
notnull

df.isnull().any()
df.notnull().all()
  • 丢弃缺失值
df.dropna(how="all") // 默认为any
df.dropna(how="any",axis=0) //指定行,只要该行有空值就删除。
df.dropna(thresh=4) // 非空值的门槛
df.dropna(inplace=True) //指定是否就地修改,默认为False。
df.dropna(axis=0, how="all", subset=[0, 1])//subset 当删除的时候,我们考虑的其他轴方向的子集。即当我们删除行(axis=0)的时候,我们考虑的列的子集。

对与how属性,all的含义是只有该行或者列全部为空值时才删除;any则是只要该行或列存在空值就删除。因此,有时候how属性并不适用于丢弃缺失值。
对于thresh属性,该参数用来指定非空值的门槛。当某行(列)存在的非空值达到该门槛时,则该行(列)保留,否则,删除该行(列)。
对于subset属性,就spider.csv文件而言,axis=0指定行,subset=[0,1]考虑第一列和第二列,huo=“all”,则说明当第一列和第二列的值都为空,则删除该行。

  • 填充缺失值
df.fillna(999) //对所有的空值进行填充,填充成指定参数value的值,这里是将所有空值用999填充。
df.fillna({3:-1000, 4:-2000})//value的值可以是字典,key用来指定列标签,value用来指定该列对应的填充值。
df.fillna(method="bfill")//指定前值还是后值填充,适用于具有趋势发展的数据。例如温度,股市。
df.fillna(value=-99, limit=2)
df.fillna(method="ffill", limit=1)

对于limit参数, 用来限制填充的数量。如果指定了method参数,则limit用来表示最多连续填充的数量,对填充的总数没有影响。
如果没有指定method(用value进行填充),则limit用来表示最多填充次数(总数)。

无效值处理

  • 检测无效值

    可以通过DataFrame对象的describe方法查看数据的统计信息。不同类型的列,统计信息也不太相同。

df.describe()//查看统计信息
df[0,1,2].describe()//指定列产看统计信息

重复值处理
在处理数据中,可能会出现重复的数据,我们通常需要将重复的记录删除。

  • 发现重复值
    我们可以通过duplicated方法来发现重复值。该方法返回Series类型的对象,值为布尔类型,表示是否与上一行重复。

参数说明:

  • subset:指定依据哪些列判断是否重复,默认为所有列。
  • keep:指定记录被标记为重复(True)的规则。默认为first。
a = pd.DataFrame([[1, 2], [1, 3], [1, 2], [2, 3], [1, 3]])
display(a)
a.duplicated().any()//判断当前记录是否与之前的记录重复,如果重复,返回True,否则返回False# 该方法会返回一个Series类型。Series中的每个数据为布尔类型(bool)。
a.duplicated(subset=[0,1])//subset参数,用来指定哪些标签(列)作为判断重复的依据(子集)。如果没有指定,则为所有标签。
a.duplicated(keep=False)

注意:
对于keep参数,可选的参数为first,last,false。

  • first:第一次出现的记录为False,其余出现的记录为True。
  • last:最后一次出现的记录为False,其余出现的记录为True。
  • False:所有重复记录,均为True。
  • 删除重复值
    通过drop_duplicates可以删除重复值。

    参数说明:

  • subset:指定依据哪些列判断是否重复,默认为所有列。
  • keep:指定记录删除(或保留)的规则。默认为First。
  • inplace:指定是否就地修改,默认为False。
a.drop_duplicates()
a.drop_duplicates(subset=[0])//用来指定判断重复所依据的列。默认为所有列。
a.drop_duplicates(subset=[0], keep=False)//keep参数:与duplicated的keep参数意义相同。
df[df.duplicated(keep=False)]//获取所有重复的记录。

数据过滤

可以使用布尔数组或者索引数组的方式来过滤数据。
另外,也可以用DataFrame类的query方法来进行数据过滤。在query方法中也可以使用外面定义的变量,需要在变量前加上@。

# 1 使用我们之前的方式。
df = df[(df[3] > 100) & (df[4] > 500)]//使用布尔表达式过滤
# 可以使用DataFrame的query方法。
df.columns = ["date", "url", "infor", "value1", "value2"]
df.query("value1 > 100 and value2 > 500")

def get_record(min_, max_):
    # 如果query方法需要使用外部定义的变量,则在变量名称前面加上@。
    return df.query("value1 > @min_ and value1 < @max_")

get_record(100, 105)

数据转换

应用与映射
Series与DataFrame对象可以进行行(列)或元素级别的映射转换操作。对于Series,可以调用apply或map方法。对于DataFrame,可以调用apply或applymap方法。

  • apply:通过函数实现映射转换。【Series传递元素,DataFrame传递行或列。】
  • map:对当前Series的值进行映射转换。参数可以是一个Series,一个字典或者是一个函数。
  • applymap:通过函数实现元素级的映射转换。

替换
Series或DataFrame可以通过replace方法可以实现元素值的替换操作。

  • to_replace:被替换值,支持单一值,列表,字典,正则表达式。
  • regex:是否使用正则表达式,默认为False。

字符串矢量化计算

Series类型具有str属性(StringMethods类型),可以支持字符串的矢量化计算。StringMethods类中提供的方法基本与Python中str类型的方法名称相同,功能也对应相同。

说明:

  • 字符串矢量化计算要求Series的数据是字符串类型。
# Series 类型的str属性(StringMethods类型),该类提供了很多方法,可以进行字符串的矢量化运算。
s = pd.Series(["abcabsdf", "dabefabdsf", "gabhkabdsf"])
s.str.upper()
s.str.startswith("a")//判断所有字符串元素是否是a开头,返回布尔值
s.str.extract("ab(\w+?)ab(\w+?)", expand=False)
s = pd.Series(["abc,sdf", "dabe,abdsf", "gabh,abdsf"])
s.str.split(",", expand=True)//expand 可以将数据进行张开(变成一个DataFrame)
# 注意,Series的str属性只能是在Series的数据类型是字符串时,才能使用。

数据合并

  • concat

我们可以通过DataFrame或Series类型的concat方法,来进行连接操作,连接时,会根据索引进行对齐。

  • axis:指定连接轴,默认为0。

  • join:指定连接方式,默认为外连接。【outer:并集,inner:交集】

  • keys:可以用来区分不同的数据组。

  • join_axes:指定连接结果集中保留的索引。

  • ignore_index:忽略原来连接的索引,创建新的整数序列索引,默认为False。

  • append

在对行进行连接时,也可以使用Series或DataFrame的append方法。
我们还是以spider.csv数据集为例。

df1 = df.head(10)
df2 = df.tail(10)
pd.concat((df1, df2), axis=1)//axis指定合并的方向,0,竖直合并。1水平合并。
pd.concat((df1, df2), axis=1, join="inner")//在合并时,可以指定连接方式。(默认为外连接)
pd.concat((df1, df2), axis=0, keys=["data1", "data2"])//可以指定keys,生成层级索引,能够观测数据的来源。
pd.concat((df1, df2), axis=0, join_axes=[df2.columns])//可以通过join_axes指定保留的索引。
pd.concat((df1, df2),axis=0, ignore_index=True)//通过 ignore_index 设置为True,就可以忽略之前的索引,重新生成新的索引。这样就能够避免多个DataFrame进行合并时,索引重复。
df1.append(df2, ignore_index=True)
  • merge

通过pandas或DataFrame的merge方法,可以进行两个DataFrame的连接,这种连接类似于SQL中对两张表进行的join连接。

  • how:指定连接方式。可以是inner, outer, left, right,默认为inner。

  • on 指定连接使用的列(该列必须同时出现在两个DataFrame中),默认使用两个DataFrame中的所有同名列进行连接。

  • left_on / right_on:指定左右DataFrame中连接所使用的列。

  • left_index / right_index:是否将左边(右边)DataFrame中的索引作为连接列,默认为False。

  • suffixes:当两个DataFrame列名相同时,指定每个列名的后缀(用来区分),默认为_x与_y。

  • join

与merge方法类似,但是默认使用索引进行连接。

  • how:指定连接方式。可以是inner, outer, left, right,默认为left。
  • on:设置当前DataFrame对象使用哪个列与参数对象的索引进行连接。
  • lsuffix / rsuffix:当两个DataFrame列名相同时,指定每个列名的后缀(用来区分),如果不指定,列名相同会产生错误。

join与merge相似,都是类似于数据库中的join连接,但是,二者还是有区别的:
1 merge方法在列名相同的时候,存在默认的后缀(_x,_y),而join方法没有默认的后缀,需要我们显式指定。
2 merge方法默认使用所有同名字段进行等值连接,而join默认使用索引进行等值连接。
3 merge默认使用inner(内连接),join默认使用left(左外连接)
4 merge方法on参数,指定两张表的同名字段进行等值连接。而join方法on参数,指定左表中使用哪个字段与右表的
索引进行等值连接。(merge方法on参数影响两张表,而join方法on参数仅影响左表。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值