目录
前言
相关案例与解析
写在最后:
文件以及文件数据的导入与分析
1.文本文件读取
文本文件是一种由若干行字符构成的计算机文件,它是一种典型的顺序文件。
txt文件:是Windows操作系统上附带的一种文本格式,文件以.txt为后缀。
CSV文件:是Comma-Separated Values的缩写,用半角逗号(’,’)作为字段值的分隔符。
1.文本文件读取
Pandas中使用read_table来读取文本文件:
pandas.read_table(filepath_or_buffer, sep=’\t’, header=’infer’, names=None, index_col=None, dtype=None, engine=None, nrows=None)
Pandas中使用read_csv函数来读取CSV文件:
pandas.read_csv(filepath_or_buffer, sep=’,’, header=’infer’, names=None, index_col=None, dtype=None, engine=None, nrows=None)
read_table和read_csv常用参数及其说明: filepath:接收string,代表文件路径,无默认 sep:接收string,代表分隔符。read_csv默认为“,”,read_table默认为制表符“\t”,如果分隔符指定错误,在读取数据的时候,每一行数据将连成一片 header:接收int或sequence,表示将某行数据作为列名,默认为infer,表示自动识别 names:接收array,表示列名,默认为None index_col:接收int、sequence或False,表示索引列的位置,取值为sequence则代表多重索引,默认为None dtype:接收dict,代表写入的数据类型(列名为key,数据格式为values),默认为None engine:接收c或者python,代表数据解析引擎,默认为c nrows:接收int,表示读取前n行,默认为None
文本文件的存储: 文本文件的存储和读取类似,结构化数据可以通过pandas中的to_csv函数实现以CSV文件格式存储文件。 DataFrame.to_csv(path_or_buf = None, sep = ’,’, na_rep, columns=None, header=True, index=True, index_label=None, mode=’w’, encoding=None)
1、Excel文件的读取: Pandas提供了read_excel函数读取“xls”和“xlsx”两种excel文件,其格式为: pandas.read_excel(io【路径】, sheetname【子表名】, header=0【列索引(表头)】, index_col=None【行索引】, names=None, dtype) read_excel函数和read_table函数的部分参数相同 参数说明: io:接收string,表示文件路径,无默认 sheetname:接收string、int,代表excel表内数据的分表位置,默认为0 header:接收int或sequence,表示将某行数据作为列名,默认为infer,表示自动识别 name:接收int、sequence或者False,表示索引列的位置,取值为sequence则代表多重索引,默认为None index_col:接收int、sequence或者False,表示索引列的位置,取值为sequence则代表多重索引,默认为None dtype:接收dict,代表写入的数据类型(列名为key,数据格式为values),默认为None 2. Excel文件的存储 将文件存储为Excel文件,可使用to_excel方法。其语法格式如下: DataFrame.to_excel(excel_writer=None, sheetname=None’, na_rep=”, header=True, index=True, index_label=None, mode=’w’, encoding=None) 与 to_csv方法的常用参数基本一致,区别之处在于指定存储文件的文件路径参数excel_writer,增加了一个sheetnames参数,用来指定存储的Excel sheet的名称,默认为sheet1。
JSON是一种轻量级的数据交互格式。可以按照JSON指定的格式去组织和封装数据,JSON本质上是一个带有特定格式的字符串。 主要功能:json就是一种在各个编程语言中流通的数据格式,负责不同编程语言中的数据传递和交互。各种编程语言存储数据的容器不尽相同,在Python中有字典dict这样的数据类型, 而其它语言可能没有对应的字典。为了让不同的语言都能够相互通用的互相传递数据,JSON就是一种非常良好的中转数据格式。
Pandas 读取MySQL数据: 首先安装MySQLdb包,读取的代码为: import pandas as pd import MySQLdb conn = MySQLdb.connect(host[主机] = host,port[端口] = port,user = username,passwd = password,db[数据库名] = db_name) df = pd.read_sql('select * from table_name',con = conn) #读入数据 conn.close()
存储MySQL数据 同样的,存储数据的方法有tocsv,toexcel等,那要将DataFrame存储到数据库中,我们同样可以使用to_sql方法来完。 其方法的参数如下: to_sql(name, con, flavor=None, schema=None, if_exists='fail', index=True, index_label=None, chunksize=None, dtype=None) (1)name参数为存储的表名;(2)con参数为连接数据库,这里和读取有区别,不能用pymysql连接;(3)if_exists参数用于判断是否有重复表名。填写fail表示:如果有重复表名,就不保存。填写replace用作替换。填写append,就在该表中继续插入数据。
例5-3 merge的默认合并数据
merge函数是通过一个或多个键将两个DataFrame按行合并起来,与SQL中的 join 用法类似,Pandas中的数据合并merge( )函数格式如下: merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None) 参数说明: left:参与合并的左侧DataFrame right:参与合并的右侧DataFrame how:连接方法:inner,left,right,outer on:用于连接的列名 left_on:左侧DataFrame中用于连接键的列 right_on:右侧DataFrame中用于连接键的列 left_index:左侧DataFrame中行索引作为连接键 right_index:右侧DataFrame中行索引作为连接键 sort:合并后会对数据排序,默认为True suffixes:修改重命名
In [17]:
import pandas as pd
import numpy as np
In [18]:
price = pd.DataFrame({'fruit':['apple','grape','orange','orange'],
'price':[8,7,9,11]})
amount = pd.DataFrame({'fruit':['apple','grape','orange'],
'amout':[5,11,8]})
display(price,amount,pd.merge(price,amount))#默认的left与right
fruit | price | |
---|---|---|
0 | apple | 8 |
1 | grape | 7 |
2 | orange | 9 |
3 | orange | 11 |
fruit | amout | |
---|---|---|
0 | apple | 5 |
1 | grape | 11 |
2 | orange | 8 |
fruit | price | amout | |
---|---|---|---|
0 | apple | 8 | 5 |
1 | grape | 7 | 11 |
2 | orange | 9 | 8 |
3 | orange | 11 | 8 |
例5-4 指定合并的列名
In [19]:
price = pd.DataFrame({'fruit':['apple','grape','orange','orange'],
'price':[8,7,9,11]})
amount = pd.DataFrame({'fruits':['apple','grape','orange'],
'amout':[5,11,8]})
display(pd.merge(price,amount,left_on = 'fruit',right_on = 'fruits'))#左右连接时加入的列名称
fruit | price | fruits | amout | |
---|---|---|---|---|
0 | apple | 8 | apple | 5 |
1 | grape | 7 | grape | 11 |
2 | orange | 9 | orange | 8 |
3 | orange | 11 | orange | 8 |
例5-5 左连接
In [20]:
price = pd.DataFrame({'fruit':['apple','grape','orange','banana'],
'price':[8,7,9,11]})
amount = pd.DataFrame({'fruit':['apple','grape','orange'],
'amout':[5,11,8]})
display(pd.merge(price,amount,left_on = 'fruit',right_on = 'fruit',how = 'left'))
#以price作为其连接键,少的自动填充
fruit | price | amout | |
---|---|---|---|
0 | apple | 8 | 5.0 |
1 | grape | 7 | 11.0 |
2 | orange | 9 | 8.0 |
3 | banana | 11 | NaN |
例5-6 右连接
In [21]:
price = pd.DataFrame({'fruit':['apple','grape','orange','banana'],
'price':[8,7,9,11]})
amount = pd.DataFrame({'fruit':['apple','grape','orange'],
'amout':[5,11,8]})
display(pd.merge(price,amount,left_on = 'fruit',right_on = 'fruit',how = 'right'))#以amount作为其连接键
fruit | price | amout | |
---|---|---|---|
0 | apple | 8 | 5 |
1 | grape | 7 | 11 |
2 | orange | 9 | 8 |
例5-7 merge通过多个键合并
In [22]:
left = pd.DataFrame({'key1':['one','one','two'],
'key2':['a','b','a'],'value1':range(3)})
right = pd.DataFrame({'key1':['one','one','two','two'],
'key2':['a','a','a','b'],'value1':range(4)})
display(left,right,pd.merge(left,right,on = ['key1','key2'],how = 'right'))
#多键合并merge,没有的引入缺失值
key1 | key2 | value1 | |
---|---|---|---|
0 | one | a | 0 |
1 | one | b | 1 |
2 | two | a | 2 |
key1 | key2 | value1 | |
---|---|---|---|
0 | one | a | 0 |
1 | one | a | 1 |
2 | two | a | 2 |
3 | two | b | 3 |
key1 | key2 | value1_x | value1_y | |
---|---|---|---|---|
0 | one | a | 0.0 | 0 |
1 | one | a | 0.0 | 1 |
2 | two | a | 2.0 | 2 |
3 | two | b | NaN | 3 |
例5-8 merge函数中参数suffixes的应用
In [8]:
print(pd.merge(left,right,on = 'key1'))
print(pd.merge(left,right,on = 'key1',suffixes = ('_left','_right')))
#通过suffixes将默认的_x与_y改变为_left与_right
key1 key2_x value1_x key2_y value1_y 0 one a 0 a 0 1 one a 0 a 1 2 one b 1 a 0 3 one b 1 a 1 4 two a 2 a 2 5 two a 2 b 3 key1 key2_left value1_left key2_right value1_right 0 one a 0 a 0 1 one a 0 a 1 2 one b 1 a 0 3 one b 1 a 1 4 two a 2 a 2 5 two a 2 b 3
例5-9 两个Series的数据连接
如果要合并的DataFrame之间没有连接键,就无法使用merge方法。pandas中的concat方法可以实现,默认情况下会按行的方向堆叠数据。如果在列向上连接设置axies = 1即可。
In [23]:
s1 = pd.Series([0,1],index = ['a','b'])
s2 = pd.Series([2,3,4],index = ['a','d','e'])
s3 = pd.Series([5,6],index = ['f','g'])
display(s1,s2,s3)
print(pd.concat([s1,s2,s3]))#行合并,能合并的全部合并
#print(pd.concat([s1,s2,s3],axis = 1))#列合并
a 0 b 1 dtype: int64
a 2 d 3 e 4 dtype: int64
f 5 g 6 dtype: int64
a 0 b 1 a 2 d 3 e 4 f 5 g 6 dtype: int64
例5-10 两个DataFrame的数据连接
In [24]:
data1 = pd.DataFrame(np.arange(6).reshape(2,3),columns = list('abc'))
#list将字符串转化为列表
data2 = pd.DataFrame(np.arange(20,26).reshape(2,3),columns = list('ayz'))
print(data1)
print(data2)
data = pd.concat([data1,data2])
datab = pd.concat([data1,data2],axis = 0,join = 'inner')
#有的堆叠,没有的直接NaN axis = 0在列的方向合并
#join = 'inner'求交集【实现内连接】,默认求并集
print(data)
print(datab)
a b c 0 0 1 2 1 3 4 5 a y z 0 20 21 22 1 23 24 25 a b c y z 0 0 1.0 2.0 NaN NaN 1 3 4.0 5.0 NaN NaN 0 20 NaN NaN 21.0 22.0 1 23 NaN NaN 24.0 25.0 a 0 0 1 3 0 20 1 23
例5-11 指定索引顺序
In [25]:
s1 = pd.Series([0,1],index = ['a','b'])
s2 = pd.Series([2,3,4],index = ['a','d','e'])
s3 = pd.Series([5,6],index = ['f','g'])
s4 = pd.concat([s1 * 5,s3],sort = False)#指定索引顺序
#s1 * 5与s3连接 sort = False不带索引的连接
#print('s4:\n',s4)
s5 = pd.concat([s1,s4],axis = 1,sort = False)#列上连接
s6 = pd.concat([s1,s4],axis = 1,join = 'inner',sort = False)
# s7 = pd.concat([s1,s4],axis = 1,join = 'inner',join_axis = [['b','a']],sort = False)#join_axis = [['b','a']]排序,新版没有了
display(s4,s5,s6)
s6.sort_index(ascending = False)
#sort_index进行排序 ascending说明:是否按指定列的数组升序排列,默认为True,即升序排列
a 0 b 5 f 5 g 6 dtype: int64
0 | 1 | |
---|---|---|
a | 0.0 | 0 |
b | 1.0 | 5 |
f | NaN | 5 |
g | NaN | 6 |
0 | 1 | |
---|---|---|
a | 0 | 0 |
b | 1 | 5 |
Out[25]:
0 | 1 | |
---|---|---|
b | 1 | 5 |
a | 0 | 0 |
例5-12 使用combine_first合并
如果需要合并的两个DataFrame存在重复索引,则使用merge和concat都无法正确合并,此时需要使用combine_first方法。
In [26]:
print(s6)
print(s5)
s6.combine_first(s5)#后者给前者打补丁
0 1 a 0 0 b 1 5 0 1 a 0.0 0 b 1.0 5 f NaN 5 g NaN 6
Out[26]:
0 | 1 | |
---|---|---|
a | 0.0 | 0 |
b | 1.0 | 5 |
f | NaN | 5 |
g | NaN | 6 |
数据分析之前必须要进行数据清洗
例5-13 使用isnull检测缺失值
In [27]:
string_data = pd.Series(['aardvark','artichoke',np.nan,'avocado'])
#np.nan是numpy里面的缺失值表示
print(string_data)
print(string_data.isnull())
print(string_data.isnull().sum())
0 aardvark 1 artichoke 2 NaN 3 avocado dtype: object 0 False 1 False 2 True 3 False dtype: bool 1
例5-14 使用isnull().sum()统计缺失值
In [28]:
df = pd.DataFrame(np.arange(12).reshape(3,4),columns = ['A','B','C','D'])
print(df)
#df.ix[2,:]=np.nan 版本升级后没有ix函数ix选取行和列
df.iloc[2,:] = np.nan#将第二行的数据设置为NaN
df[3] = np.nan#添加第三列为NaN
print(df)
df.isnull().sum()#统计每一列的缺失值
#isnull给的是缺失值的情况
A B C D 0 0 1 2 3 1 4 5 6 7 2 8 9 10 11 A B C D 3 0 0.0 1.0 2.0 3.0 NaN 1 4.0 5.0 6.0 7.0 NaN 2 NaN NaN NaN NaN NaN
Out[28]:
A 1 B 1 C 1 D 1 3 3 dtype: int64
例5-16 使用info方法查看DataFrame缺失值
In [29]:
df.info()
#info统计的是数据当中有值的情况
RangeIndex: 3 entries, 0 to 2 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 A 2 non-null float64 1 B 2 non-null float64 2 C 2 non-null float64 3 D 2 non-null float64 4 3 0 non-null float64 dtypes: float64(5) memory usage: 248.0 bytes
1)删除缺失值 在缺失值的处理方法中,删除缺失值是常用的方法之一。通过dropna方法可以删除具有缺失值的行。 dropna方法的格式: dropna(axis=0, how=‘any’,thresh=None,subset=None, inplace=False) 参数说明: axis:默认为axis=0,当某行出现缺失值时,将该行丢弃并返回,当axis=1,当某列出现缺失值时,将该列丢弃 how:表示删除的形式。any表示只要有缺失值存在就执行删除操作。all表示当且仅当全部为缺失值时执行删除操作。默认为any。 thresh:阈值设定,当行列中非空值的数量少于给定的值就将该行丢弃 subset:表示进行去重的列∕行,如:subset=['a','d'], 即丢弃子列 a d 中含有缺失值的行 inplace:bool取值,默认False, 当inplace= True,即对原数据操作,无返回值
例5-17 Series的dropna用法
In [31]:
from numpy import nan as NA
data = pd.Series([1,NA,3.5,NA,7])
print(data)
print(data.dropna())#删除缺失值
0 1.0 1 NaN 2 3.5 3 NaN 4 7.0 dtype: float64 0 1.0 2 3.5 4 7.0 dtype: float64
例5-18布尔型索引选择过滤非缺失值
In [21]:
not_null = data.notnull()#notnull非空为True,为空为False
print(not_null)
print(data[not_null])#非空的显示一下
0 True 1 False 2 True 3 False 4 True dtype: bool 0 1.0 2 3.5 4 7.0 dtype: float64
例5-19 DataFrame对象的dropna默认参数使用
In [7]:
from numpy import nan as NA
data = pd.DataFrame([[1.,5.5,3.],[1.,NA,NA],[NA,NA,NA],[NA,5.5,3.]])
print(data)
cleaned = data.dropna()#只要有缺失值就删除
print(cleaned)
0 1 2 0 1.0 5.5 3.0 1 1.0 NaN NaN 2 NaN NaN NaN 3 NaN 5.5 3.0 0 1 2 0 1.0 5.5 3.0
例5-20 传入参数all
In [23]:
print(data)
data.dropna(how = 'all')#当这一行全部为空才删除
0 1 2 0 1.0 5.5 3.0 1 1.0 NaN NaN 2 NaN NaN NaN 3 NaN 5.5 3.0
Out[23]:
0 | 1 | 2 | |
---|---|---|---|
0 | 1.0 | 5.5 | 3.0 |
1 | 1.0 | NaN | NaN |
3 | NaN | 5.5 | 3.0 |
例5-21 dropna中的axis参数应用
In [8]:
data = pd.DataFrame([[1.,5.5,NA],[1.,NA,NA],[NA,NA,NA],[NA,5.5,NA]])
print(data)
data.dropna(axis = 1,how = 'all')#对列操作
0 1 2 0 1.0 5.5 NaN 1 1.0 NaN NaN 2 NaN NaN NaN 3 NaN 5.5 NaN
Out[8]:
0 | 1 | |
---|---|---|
0 | 1.0 | 5.5 |
1 | 1.0 | NaN |
2 | NaN | NaN |
3 | NaN | 5.5 |
例5-22 dropna中的thresh参数应用
In [25]:
df.dropna(thresh = len(df) * 0.9)#数据当中超过1%就删除 这个是比例的写法
df = pd.DataFrame(np.random.randn(7,3))
print(df)
df.iloc[:4,1] = NA#0-3行的第一列设置为NaN
df.iloc[:2,2] = NA#0-1行的第二列设置为NaN
print(df)
df.dropna(thresh = 2)#直接给值的写法,此处指的是在行当中,有两个NaN的删除
0 1 2 0 1.799892 0.071073 -0.606270 1 0.364085 -0.501062 0.137286 2 -0.110193 -1.313506 -2.448223 3 0.084872 -0.450108 1.722744 4 -0.360017 -0.993709 0.543938 5 1.347388 0.101055 1.618077 6 -0.870977 -1.018025 -0.586990 0 1 2 0 1.799892 NaN NaN 1 0.364085 NaN NaN 2 -0.110193 NaN -2.448223 3 0.084872 NaN 1.722744 4 -0.360017 -0.993709 0.543938 5 1.347388 0.101055 1.618077 6 -0.870977 -1.018025 -0.586990
Out[25]:
0 | 1 | 2 | |
---|---|---|---|
2 | -0.110193 | NaN | -2.448223 |
3 | 0.084872 | NaN | 1.722744 |
4 | -0.360017 | -0.993709 | 0.543938 |
5 | 1.347388 | 0.101055 | 1.618077 |
6 | -0.870977 | -1.018025 | -0.586990 |
例5-23 通过字典形式填充缺失值
2)填充缺失值 缺失值所在的特征为数值型时,通常利用其均值、中位数和众数等描述其集中趋势的统计量来填充;缺失值所在特征为类别型数据时,则选择众数来填充。 Pandas库中提供了缺失值替换的方法fillna,格式如下:DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None) 参数说明: value:用于填充缺失值的标量值或字典对象 method:插值的方式 axis:待填充的轴,默认为0 inplace:修改调用者对象而不产生副本 limit:(对于前向和后向填充)可以连接填充的最大数量
In [26]:
df = pd.DataFrame(np.random.randn(5,3))
print(df)
df.iloc[:3,1] = NA#0-2行的第一列
df.iloc[:2,2] = NA#0-1行的第二列
print(df)
df.fillna(9)#缺失的值用9填充
#df.fillna({1:0.88,2:0.66})#不同的列填充的时候,用字典来填充
0 1 2 0 2.307952 -0.895185 -0.407553 1 -0.143182 -0.247782 0.400249 2 -0.471407 0.711509 -1.197661 3 1.408783 0.142203 -0.598173 4 0.693533 1.397422 -2.890545 0 1 2 0 2.307952 NaN NaN 1 -0.143182 NaN NaN 2 -0.471407 NaN -1.197661 3 1.408783 0.142203 -0.598173 4 0.693533 1.397422 -2.890545
Out[26]:
0 | 1 | 2 | |
---|---|---|---|
0 | 2.307952 | 9.000000 | 9.000000 |
1 | -0.143182 | 9.000000 | 9.000000 |
2 | -0.471407 | 9.000000 | -1.197661 |
3 | 1.408783 | 0.142203 | -0.598173 |
4 | 0.693533 | 1.397422 | -2.890545 |
例5-24 fillna中method的应用
In [29]:
df = pd.DataFrame(np.random.randn(6,3))
df.iloc[2:,1] = NA#第二行开始的第一列开始填充NaN
df.iloc[4:,2] = NA#第四行开始的第二列开始填充NaN
print(df)
df.fillna(method = 'ffill')#填充时按照前向填充
#‘bfill’就是将缺失值按照后面一个值进行填充,
#'ffill' 就是将缺失值按照前面一个值进行填充。
0 1 2 0 -0.118091 0.453487 -1.223563 1 -2.031957 0.374827 2.914959 2 1.041202 NaN 1.518597 3 1.732091 NaN -0.846756 4 -1.026056 NaN NaN 5 -1.454032 NaN NaN
Out[29]:
0 | 1 | 2 | |
---|---|---|---|
0 | -0.118091 | 0.453487 | -1.223563 |
1 | -2.031957 | 0.374827 | 2.914959 |
2 | 1.041202 | 0.374827 | 1.518597 |
3 | 1.732091 | 0.374827 | -0.846756 |
4 | -1.026056 | 0.374827 | -0.846756 |
5 | -1.454032 | 0.374827 | -0.846756 |
例5-25 用Series的均值填充
In [28]:
data = pd.Series([1.,NA,3.5,NA,7])
print(data)
data.fillna(data.mean())#求均值之后,用求出来的均值填充缺失值
0 1.0 1 NaN 2 3.5 3 NaN 4 7.0 dtype: float64
Out[28]:
0 1.000000 1 3.833333 2 3.500000 3 3.833333 4 7.000000 dtype: float64
例5-26 在DataFrame当中用均值填充
In [9]:
df = pd.DataFrame(np.random.randn(4,3))
df.iloc[2:,1] = NA
df.iloc[3:,2] = NA
print(df)
df[1] = df[1].fillna(df[1].mean())#df1里面的用df1的均值填充
print(df)
0 1 2 0 -1.956132 0.289002 1.171357 1 -0.248903 0.797688 0.796596 2 0.964767 NaN -0.198751 3 -2.041525 NaN NaN 0 1 2 0 -1.956132 0.289002 1.171357 1 -0.248903 0.797688 0.796596 2 0.964767 0.543345 -0.198751 3 -2.041525 0.543345 NaN
In [32]:
#对与fillna的参数,可以通过df.fillna? 来帮助查看
df.fillna?
例5-27 判断DataFrame的重复数据
在DataFrame中利用duplicates方法判断各行是否有重复数据。duplicates方法返回一个布尔值的series,反映每一行是否与之前的行重复。 Pandas通过drop_duplicates删除重复的行,格式为: drop_duplicates(self, subset=None, keep=’first’, inplace=False) 参数说明: subset:接收string或sequence,表示进行去重的列,默认全部列 keep:接收string,表示重复时保留第几个数据,‘first’保留第一个,‘last’保留最后一个,‘false’只要有重复都不保留,默认为first inplace:接收布尔型数据,表示是否在原表上进行操作,默认为False
使用drop_duplicates方法去重时,当且仅当subset参数中的特征重复时候才会执行去重操作,去重时可以选择保留哪一个或者不保留
In [33]:
data = pd.DataFrame({'k1':['one','two'] * 3 + ['two'],
'k2':[1,1,2,3,1,4,4],
'k3':[1,1,5,2,1,4,4]})
print(data)
data.duplicated()#.duplicated()判断各行是否有重复数据返回的为布尔序列
k1 k2 k3 0 one 1 1 1 two 1 1 2 one 2 5 3 two 3 2 4 one 1 1 5 two 4 4 6 two 4 4
Out[33]:
0 False 1 False 2 False 3 False 4 True 5 False 6 True dtype: bool
例5-28 每行各个字段都相同时去重
In [34]:
data.drop_duplicates()#去除重复行
Out[34]:
k1 | k2 | k3 | |
---|---|---|---|
0 | one | 1 | 1 |
1 | two | 1 | 1 |
2 | one | 2 | 5 |
3 | two | 3 | 2 |
5 | two | 4 | 4 |
例5-29 指定部分列重复时去重
In [36]:
data.drop_duplicates(['k2','k3'])
#k2与k3列当中重复时删除重复的行
Out[36]:
k1 | k2 | k3 | |
---|---|---|---|
0 | one | 1 | 1 |
2 | one | 2 | 5 |
3 | two | 3 | 2 |
5 | two | 4 | 4 |
例5-30去重时保留最后出现的记录
In [37]:
data.drop_duplicates(['k2','k3'],keep = 'last')
#keep默认保留的数据为第一个出现的记录,通过传入keep = ’last’可以保留最后一个出现的记录。
Out[37]:
k1 | k2 | k3 | |
---|---|---|---|
2 | one | 2 | 5 |
3 | two | 3 | 2 |
4 | one | 1 | 1 |
6 | two | 4 | 4 |
简单的数据统计方法中常用散点图、箱线图和3σ法则检测异常值。 散点图方法: 通过数据分布的散点图发现异常数据。 箱线图分析: 利用数据中的五个统计量(最小值、下四分位数、中位数、上四分位数和最大值)来描述数据。 3σ法则: 在3σ原则下,异常值被定义为一组测定值中与平均值的偏差超过3倍标准差的值。
例5-31 使用散点图检测异常值
In [2]:
wdf = pd.DataFrame(np.arange(20),columns = ['W'])
wdf['Y'] = wdf['W'] * 1.5 + 2#新增的Y由X生成
#print(wdf)
wdf.iloc[3,1] = 128#对第三行第一列值进行修改
wdf.iloc[18,1] = 150#对第十八行的第一列的值进行修改
#print(wdf)
wdf.plot(kind = 'scatter',x = 'W',y = 'Y')
#散点图方法: 通过数据分布的散点图发现异常数据
Out[2]:
例5-32 使用箱线图分析异常值
箱线图利用数据中的五个统计量(最小值、下四分位数、中位数、上四分位数和最大值)来描述数据,它也可以粗略地看出数据是否具有对称性、分布的分散程度等信息
In [14]:
import matplotlib.pyplot as plt
%matplotlib inline
plt.boxplot(wdf['Y'].values,notch = True)#对Y的值做箱线图,notch是否凹陷
#.boxplot箱线图函数写法
Out[14]:
{'whiskers': [, ], 'caps': [ , ], 'boxes': [ ], 'medians': [ ], 'fliers': [ ], 'means': []}
例5-33 使用3σ法则检测异常值
3σ法则
若数据服从正态分布,在3σ原则下,异常值被定义为一组测定值中与平均值的偏差超过3倍标准差的值,因为在正态分布的假设下,距离平均值3σ之外的值出现的概率小于0.003。因此根据小概率事件,可以认为超出3σ之外的值为异常数据。
In [21]:
def outRange(S):
blidx = (S.mean() - 3 * S.std() > S)| (S.mean() + 3 * S.std() < S)#平均值+-方差的绝对值
idx = np.arange(S.shape[0])[blidx]
outRange = S.iloc[idx]
return outRange
outier = outRange(wdf['Y'])#outRange
outier
Out[21]:
18 150.0 Name: Y, dtype: float64
例5-34 使用replace替换数据值
In [22]:
data = {'姓名':['李红','小明','马芳','国志'],
'性别':['0','1','0','1'],
'籍贯':['北京','甘肃','','上海']}
df = pd.DataFrame(data)
print(df)
df = df.replace('','不详')#搜索到空缺值用不详来替代
print(df)
姓名 性别 籍贯 0 李红 0 北京 1 小明 1 甘肃 2 马芳 0 3 国志 1 上海 姓名 性别 籍贯 0 李红 0 北京 1 小明 1 甘肃 2 马芳 0 不详 3 国志 1 上海
例5-35 使用replace传入列表实现多值替换
In [23]:
df = df.replace(['不详','甘肃'],['兰州','兰州'])
#不详与甘肃用兰州和兰州来替换
print(df)
姓名 性别 籍贯 0 李红 0 北京 1 小明 1 兰州 2 马芳 0 兰州 3 国志 1 上海
例5-36 作用replace传入字典实现多值替换
In [25]:
df = df.replace({'1':'男','0':'女'})#1用男,0用女
print(df)
姓名 性别 籍贯 0 李红 女 北京 1 小明 男 兰州 2 马芳 女 兰州 3 国志 男 上海
例5-37 使用map方法映射数据
In [26]:
data = {'姓名':['李红','小明','马芳','国志'],
'性别':['0','1','0','1'],
'籍贯':['北京','兰州','兰州','上海']}
df = pd.DataFrame(data)
print(df)
df['成绩'] = [58,86,91,78]#自动加载成绩这一列
print(df)
def grade(x):
if x>=90:
return '优'
elif 70<=x<90:
return '良'
elif 60<=x<70:
return '中'
else:
return '差'
df['等级'] = df['成绩'].map(grade)
#等级用map里面的函数grade来赋值
display(df)
姓名 性别 籍贯 0 李红 0 北京 1 小明 1 兰州 2 马芳 0 兰州 3 国志 1 上海 姓名 性别 籍贯 成绩 0 李红 0 北京 58 1 小明 1 兰州 86 2 马芳 0 兰州 91 3 国志 1 上海 78
姓名 | 性别 | 籍贯 | 成绩 | 等级 | |
---|---|---|---|---|---|
0 | 李红 | 0 | 北京 | 58 | 差 |
1 | 小明 | 1 | 兰州 | 86 | 良 |
2 | 马芳 | 0 | 兰州 | 91 | 优 |
3 | 国志 | 1 | 上海 | 78 | 良 |
数据标准差:
离差标准化是对原始数据所做的一种线性变换,将原始数据的数值映射到[0,1]区间。转换公式如下所示。
1=((−min))⁄((max−min) )
标准差标准化又称零均值标准化或z分数标准化,是当前使用最广泛的数据标准化方法。
1=((−))⁄
例5-38 数据的离差标准化
In [27]:
def MinMaxScale(data):
data = (data - data.min())/(data.max() - data.min())
return data
x = np.array([[1.,-1,2.],[2.,0.,0.],[0.,1.,-1.]])
print(x)
x_scaled = MinMaxScale(x)
print(x_scaled)
#最大值为1,最小值为0-1之间的最小值,按照比例实现离差标准化
[[ 1. -1. 2.] [ 2. 0. 0.] [ 0. 1. -1.]] [[0.66666667 0. 1. ] [1. 0.33333333 0.33333333] [0.33333333 0.66666667 0. ]]
例5-39 数据的标准差标准化
In [30]:
def StandardScale(data):
data = (data - data.mean())/data.std()
return data
x = np.array([[1.,-1.,2.],[2.,0.,0.],[0.,1.,-1.]])
print(x)
x_scaled = StandardScale(x)
print(x_scaled)
[[ 1. -1. 2.] [ 2. 0. 0.] [ 0. 1. -1.]] [[ 0.52128604 -1.35534369 1.4596009 ] [ 1.4596009 -0.41702883 -0.41702883] [-0.41702883 0.52128604 -1.35534369]]
数据变换:
类别型数据就是可以用来分类表示的数据
1、哑变量( Dummy Variables)是用以反映质的属性的一个人工变量,是量化了的自变量,通常取值为0或1。
利用pandas库中的get_dummies函数对类别型特征进行哑变量处理。
pandas.get_dummies(data, prefix = None, prefix_sep = '_', dummy_na = False, columns = None, sparse = False, drop_first=False)
参数说明:
data:接收array、DataFrame或者Series。表示需要哑变量处理的数据。无默认
prefix:接收string、string的列表或者string的dict。表示哑变量化后列名的前缀。默认为None。
prefix_sep:接收string。表示前缀的连接符。默认为‘_’。
dummy_na:接收boolean。表示是否为Nan值添加一列。默认为False。
columns:接收类似list的数据。表示DataFrame中需要编码的列名。默认为None,表示对所有object和category类型进行编码。
sparse:接收boolean。表示虚拟列是否是稀疏的。默认为False。
drop_first:接收boolean。表示是否通过从k个分类级别中删除第一级来获得k-1个分类级别。默认为False。
例5-40 数据的哑变量处理
In [31]:
df = pd.DataFrame([['green','M',10.1,'class1'],['red','L',13.5,'class2'],['blue','XL',5.3,'class1']])
df.columns = ['color','size','price','class label']
print(df)
pd.get_dummies(df)#有对应关系为1,没有的为0
#特征型变量量化
color size price class label 0 green M 10.1 class1 1 red L 13.5 class2 2 blue XL 5.3 class1
Out[31]:
price | color_blue | color_green | color_red | size_L | size_M | size_XL | class label_class1 | class label_class2 | |
---|---|---|---|---|---|---|---|---|---|
0 | 10.1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 |
1 | 13.5 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 |
2 | 5.3 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
连续型变量的离散化:
例5-41 cut函数的应用
In [32]:
np.random.seed(666)#随机种子
score_list = np.random.randint(25,100,size = 10)#取10个25-100的随机数
print(score_list)
bins = [0,59,70,80,100]
score_cut = pd.cut(score_list,bins)#bins是划分的区间
#连续数据等宽离散化,值域划分为相等宽度的区域,区域个数由本身指定或者用户指定
print(pd.value_counts(score_cut))#将各个区间的数目求出来
[27 70 55 87 95 98 55 61 86 76] (80, 100] 4 (0, 59] 3 (59, 70] 2 (70, 80] 1 dtype: int64
例5-42将泰坦尼克数据集中的年龄字段按下面规则分组转换为分类特征: (<=12,儿童),(<=18,青少年),(<=60,成人),(>60,老人)
In [36]:
import sys
df = pd.read_csv('titanic.csv')
display(df.head())
df['ageGroup'] = pd.cut(df['age'],bins = [0,13,19,61,sys.maxsize],
labels = ['儿童','青年人','成人','老人'])
#根据年龄进行分段 sys.maxsize系统的最大值 labels就是标签
# sys.maxsize指的是可以存储的最大值
display(df.sample(5))
survived | pclass | sex | age | sibsp | parch | fare | embarked | class | who | adult_male | deck | embark_town | alive | alone | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 3 | male | 22.0 | 1 | 0 | 7.2500 | S | Third | man | True | NaN | Southampton | no | False |
1 | 1 | 1 | female | 38.0 | 1 | 0 | 71.2833 | C | First | woman | False | C | Cherbourg | yes | False |
2 | 1 | 3 | female | 26.0 | 0 | 0 | 7.9250 | S | Third | woman | False | NaN | Southampton | yes | True |
3 | 1 | 1 | female | 35.0 | 1 | 0 | 53.1000 | S | First | woman | False | C | Southampton | yes | False |
4 | 0 | 3 | male | 35.0 | 0 | 0 | 8.0500 | S | Third | man | True | NaN | Southampton | no | True |
survived | pclass | sex | age | sibsp | parch | fare | embarked | class | who | adult_male | deck | embark_town | alive | alone | ageGroup | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
417 | 1 | 2 | female | 18.0 | 0 | 2 | 13.0000 | S | Second | woman | False | NaN | Southampton | yes | False | 青年人 |
558 | 1 | 1 | female | 39.0 | 1 | 1 | 79.6500 | S | First | woman | False | E | Southampton | yes | False | 成人 |
635 | 1 | 2 | female | 28.0 | 0 | 0 | 13.0000 | S | Second | woman | False | NaN | Southampton | yes | True | 成人 |
408 | 0 | 3 | male | 21.0 | 0 | 0 | 7.7750 | S | Third | man | True | NaN | Southampton | no | True | 成人 |
485 | 0 | 3 | female | NaN | 3 | 1 | 25.4667 | S | Third | woman | False | NaN | Southampton | no | False | NaN |
例5-43 等频法离散化连续型数据
In [38]:
print(score_list)#前面的十个整数
def SameRateCut(data,k):
k = 2
w = data.quantile(np.arange(0,1+1.0/k,1.0/k))#quantile是分位数函数,0到1+1.0/k步长为1.0/k
print(w)#w是找频率
data = pd.cut(data,w)#按照w提供的频率等分
return data
result = SameRateCut(pd.Series(score_list),3)
result.value_counts()
[27 70 55 87 95 98 55 61 86 76] 0.0 27.0 0.5 73.0 1.0 98.0 dtype: float64
Out[38]:
(73.0, 98.0] 5 (27.0, 73.0] 4 dtype: int64
本章实训
In [39]:
import pandas as pd
import numpy as np
2、获取数据
In [40]:
fdata = pd.read_excel('tips_mod.xls')
fdata.head()
Out[40]:
tatal_bill | tip | sex | smoker | day | time | size | |
---|---|---|---|---|---|---|---|
0 | 16.99 | 1.01 | Female | No | Sun | Dinner | 2.0 |
1 | 10.34 | 1.66 | Male | No | Sun | Dinner | 3.0 |
2 | 21.01 | 3.50 | Male | No | Sun | Dinner | 3.0 |
3 | 23.68 | 3.31 | Male | No | Sun | Dinner | 2.0 |
4 | 24.59 | 3.61 | Female | No | Sun | Dinner | 4.0 |
3、分析数据
In [41]:
#查看数据的描述信息
print(fdata.shape)
fdata.describe()
(244, 7)
Out[41]:
tatal_bill | tip | size | |
---|---|---|---|
count | 241.000000 | 241.000000 | 241.000000 |
mean | 19.853444 | 3.002573 | 2.568465 |
std | 8.928148 | 1.390638 | 0.955511 |
min | 3.070000 | 1.000000 | 1.000000 |
25% | 13.370000 | 2.000000 | 2.000000 |
50% | 17.810000 | 2.880000 | 2.000000 |
75% | 24.270000 | 3.600000 | 3.000000 |
max | 50.810000 | 10.000000 | 6.000000 |
In [42]:
#显示聚餐时间段time的不生复值
fdata['time'].unique()
Out[42]:
array(['Dinner', 'Diner', 'Dier', 'Lunch', nan], dtype=object)
In [43]:
#修改拼写错误的字段值
fdata.loc[fdata['time'] == 'Diner','time'] = 'Dinner'
fdata.loc[fdata['time'] == 'Dier','time'] = 'Dinner'
fdata['time'].unique()
Out[43]:
array(['Dinner', 'Lunch', nan], dtype=object)
In [44]:
#检测数据中的缺失值
fdata.isnull().sum()
Out[44]:
tatal_bill 3 tip 3 sex 2 smoker 0 day 0 time 2 size 3 dtype: int64
In [45]:
#删除一行内有两个缺失值的数据
fdata.dropna(thresh = 6,inplace = True)
fdata.isnull().sum()
Out[45]:
tatal_bill 3 tip 2 sex 1 smoker 0 day 0 time 1 size 2 dtype: int64
In [46]:
#删除sex或time为空的行
fdata.dropna(subset = ['sex','time'],inplace = True)
fdata.isnull().sum()
Out[46]:
tatal_bill 3 tip 2 sex 0 smoker 0 day 0 time 0 size 2 dtype: int64
In [47]:
#剩余有空缺的数据用平均值代替
fdata.fillna(fdata.mean(),inplace = True)
fdata.isnull().sum()
Out[47]:
tatal_bill 0 tip 0 sex 0 smoker 0 day 0 time 0 size 0 dtype: int64
此处的数据是来源与我自己的数据,想要的宝子可以私信我要奥,也希望我写的博文能帮到你们。文章当中的图片由于一些原因无法展示,希望各位宝子可以见谅哈!各位宝子也可以自行验证