1.Pandas介绍
1.Pandas简介
- 以Numpy为基础,借助Numpy模块在计算方面性能高的优势
- 基于matplotlib,能够简便的画图
2.Pandas的优势
- 增强图表可读性
- 便捷的数据处理能力
- 读取文件方便
- 封装了Matplotlib、Numpy的画图和计算
2.Pandas的数据结构
Pandas中一共有三种数据结构,分别为:Series、DataFrame和MultiIndex(老版本中叫Panel)。其中Series是一维数据结构,DataFrame是二维的表格型数据结构,MultiIndex是三维的数据结构。
1.Series
1.Series的创建
- 创建Series使用pd.Series(data=None,index=None,dtype=None)函数,参数说明:
- data:传入的数据可以是ndarray,list等
- index:索引,必须是唯一的,且与数据的长度相等。如果没有传入索引参数,则默认会自动创建一个从0-N的整数索引
- dtype: 数据的类型
- 通过已有数据创建Series
# 指定内容,默认索引
a = pd.Series(np.arange(10))
print(a)
# 指定内容,指定索引
a = pd.Series(data = [1,3,5,7], index=[1,2,3,4])
print(a)
# 通过字典数据创建
color_count = pd.Series({'red':100, 'blue':200, 'green': 500, 'yellow':1000})
2.Series的属性
Series中提供了两个属性index和values,用于操作Series对象中的索引和数据
import pandas as pd
obj = pd.Series({"one":1,"two":2,"three":3})
print(obj.index)#Index(['one', 'two', 'three'], dtype='object')
print(obj[2])#3
print(obj.values)#[1 2 3]
2.DataFrame
1.DataFrame的创建
- 创建DataFrame使用pd.DataFrame(data=None,index=None, columns=None)函数
- 函数参数:
- index:行标签。如果没有传入索引参数,则默认会自动创建一个从0-N的整数索引。
- columns:列标签。如果没有传入索引参数,则默认会自动创建一个从0-N的整数索引。
- 函数参数:
- 通过已有数据创建DataFrame
import pandas as pd
a = pd.DataFrame(np.random.randn(2,3))
print(a) # 两行三列
# 三名同学四门成绩
score = np.random.randint(40, 90, (3,4))
a = pd.DataFrame(score)
print(a)
# 给分数增加行列索引
# 构造列索引序列
subjects = ["语文","数学","英语","地理"]
# 构造行索引序列
print(a.shape)
stu = ["学生" + str(i) for i in range(a.shape[0])]
a = pd.DataFrame(score, columns = subjects, index = stu)
print(a)
2.DataFrame的属性和方法
- shape:用元组表示的DataFrame的形状
- index:DataFrame的行索引列表
- columns:DataFrame的列索引列表
- columns:DataFrame的列索引列表
- T:转置
- head(5):显示前5行内容,如果不补充参数,默认5行。填入参数N则显示前N行
- tail(5):显示后5行内容,如果不补充参数,默认5行。填入参数N则显示后N行
import pandas as pd
# 三名同学四门成绩
score = np.random.randint(40, 90, (3,4))
# 给分数增加行列索引
# 构造列索引序列
subjects = ["语文","数学","英语","地理"]
# 构造行索引序列
stu = ["学生" + str(i) for i in range(a.shape[0])]
a = pd.DataFrame(score, columns = subjects, index = stu)
print(a)
print(a.shape)
print(a.index)
print(a.columns)
print(a.values)
print(a.T)
3.DataFrame索引的设置
- 修改行列索引值
# 修改行索引
# 三名同学四门成绩
score = np.random.randint(40, 90, (3,4))
# 给分数增加行列索引
# 构造列索引序列
subjects = ["语文","数学","英语","地理"]
# 构造行索引序列
stu = ["学生" + str(i) for i in range(a.shape[0])]
a = pd.DataFrame(score, columns = subjects, index = stu)
print(a)
stu = ["学生_" + str(i) for i in range(a.shape[0])]
a.index = stu
print(a)
- 重设索引:使用reset_index(drop=False)函数设置新的下标索引。
- drop为True表示删除原来的索引值
- drop默认为False,表示不删除原来索引
- 以某列值设置为新的索引:set_index(keys, drop=True)
- keys:列索引名成或者列索引名称的列表
- drop : boolean, default True.当做新的索引,删除原来的列
3.MultiIndex(老版本中叫做Pannel)
多级索引(也称层次化索引)是pandas的重要功能,可以在Series、DataFrame对象上拥有2个以及2个以上的索引。MultiIndex是三维的数据结构。
1.MultiIndex的属性
- index属性:
- names:levels的名称
- levels:每个level的元组值
4.索引操作
测试数据(学生成绩表)如下图:
- 使用行列索引(先列后行)
# 1.获取学生2的数学成绩
a["数学"]["学生2"]#62
# a["学生2"]["数学"]#error
# a[2:3,1:2]#error
- 结合loc或者iloc使用索引
- 使用loc:只能指定行列索引的名字
- 使用iloc可以通过索引的下标去获取
# 获取学生0和学生1的数学和英语成绩
a.loc["学生0":"学生1","数学":"英语"]
数学 英语
学生0 84 54
学生1 70 60
# 获取前两名学生,前三门成绩的结果
a.iloc[0:2:1,0:3:1]
语文 数学 英语
学生0 54 73 51
学生1 60 50 68
- 使用ix组合索引:使用ix进行下标和名称组合做索引
# 获取前两名学生,语文,数学,地理三门成绩的结果
# a.ix[0:2:1,['语文','数学','地理']] error,ix已被弃用
# 推荐使用loc和iloc的方式获取
print(a.loc[a.index[0:2], ['语文','数学','地理']])
语文 数学 地理
学生0 89 70 84
学生1 40 74 75
print(a.iloc[0:2:1, a.columns.get_indexer(['语文','数学','地理'])])
5.赋值操作
# 对a中的地理列的所有值重新赋值为0
a['地理'] = 1
a.地理 = 1
6.排序
排序有两种形式,一种对于索引进行排序,一种对于内容进行排序
1.DataFrame排序
- 使用
对象.sort_values(by=,ascending=)
对单个键或者多个键进行排序。函数参数如下:- by:指定排序参考的键
- ascending:默认升序
- ascending=False:降序
- ascending=True:升序
#按照数学成绩对学生成绩表进行排序
a = a.sort_values(by='数学', ascending=True)
print(a)
#按照数学成绩和语文成绩进行排序
a = a.sort_values(by=['语文','数学'], ascending=True)
- 使用
对象.sort_index()
给索引进行排序
# 三名同学四门成绩
score = np.random.randint(40, 90, (3,4))
a = pd.DataFrame(score)
# 给分数增加行列索引
# 构造列索引序列
subjects = ["语文","数学","英语","地理"]
# 构造行索引序列
stu = [2,4,1]
a = pd.DataFrame(score, columns = subjects, index = stu)
print(a)
a = a.sort_index()
print(a)
2.Series排序
- 使用
series.sort_values(ascending=True)
函数进行排序
# 三名同学四门成绩
score = np.random.randint(40, 90, (3,4))
a = pd.DataFrame(score)
# 给分数增加行列索引
# 构造列索引序列
subjects = ["语文","数学","英语","地理"]
# 构造行索引序列
stu = [2,4,1]
a = pd.DataFrame(score, columns = subjects, index = stu)
a = a['数学']
print(type(a)) #<class 'pandas.core.series.Series'>
print(a)
a = a.sort_values(ascending=True)
2. 使用series.sort_index()
函数对索引进行排序
# 三名同学四门成绩
score = np.random.randint(40, 90, (3,4))
a = pd.DataFrame(score)
# 给分数增加行列索引
# 构造列索引序列
subjects = ["语文","数学","英语","地理"]
# 构造行索引序列
stu = [2,4,1]
a = pd.DataFrame(score, columns = subjects, index = stu)
a = a['数学']
print(type(a)) #<class 'pandas.core.series.Series'>
print(a)
a = a.sort_index()
print(a)
7.DataFrame运算
1.算数运算
- add(other)
- sub(other)
# 对学生成绩表中的语文成绩增加20分
# 对学生成绩表中的数学成绩减少20分
a['语文'].add(20)
a['数学'].sub(20)
2.逻辑运算
- 逻辑运算符号
# 筛选学生成绩表中语文成绩大于60的数据
a['语文'] > 60
学生0 True
学生1 True
学生2 True
Name: 语文, dtype: bool
# 逻辑判断的结果可以作为筛选的依据
a[a['语文'] > 60]
语文 数学 英语 地理
学生0 75 88 85 76
学生1 67 89 45 44
学生2 68 74 77 89
- 逻辑运算函数
- query(expr):expr为查询字符串
a.query("语文>=60 & 数学>80") 语文 数学 英语 地理 学生2 66 86 62 50
- isin(values)
# 获取语文成绩在60分或者62分的学生数据 a[a["语文"].isin([60,62])]
3.统计运算
- describe()函数:对数据进行综合分析,能够直接得出很多统计结果,count, mean, std, min, max 等
a.describe()
2. 统计函数
3. 累计统计函数
4.自定义运算
- 使用apply(func, axis=0)函数。函数参数如下:
- func:自定义函数
- axis=0:默认是列,axis=1为行进行运算
#定义一个对列,最大值-最小值的函数
data[['open', 'close']].apply(lambda x: x.max() - x.min(), axis=0)
8.Pandas画图
1.DataFrame的画图函数
DataFrame画图使用pandas.DataFrame.plot(kind='line')函数。参考官网
2.Series的画图函数
9.文件读取和存取
pandas支持多种文件格式的IO操作。
1.CSV文件格式的文件读取和存储
- 读取:使用
pandas.read_csv(filepath_or_buffer, sep =',', usecols )
函数- filepath_or_buffer:文件路径
- sep :分隔符,默认用","隔开
- usecols:指定读取的列名,列表形式
- names:指定列名
# 示例
import pandas as pd
# 读取文件,只获取指定的列数据
data = pd.read_csv("./adult.data.csv", usecols=['age','Education'])
- 存储:使用
DataFrame.to_csv(path_or_buf=None, sep=', ’, columns=None, header=True, index=True, mode='w', encoding=None)
函数- path_or_buf :文件路径
- sep :分隔符,默认用","隔开
- columns :选择需要的列索引
- header :boolean or list of string, default True,header表示是否写进列索引值
- index:是否写进行索引
- mode:'w':重写, 'a' 追加
import pandas as pd
data = pd.read_csv("./adult.data.csv", usecols=['age','Education'])
# index=False表示不写进行索引,将age列的数据写进csv文件中
data[:10].to_csv("./test.csv", columns=['age'],index=False)
data = pd.read_csv("./test.csv")
- 读取CSV文件遇到的问题:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd4 in position 23: invalid continuation byte
解决办法:
最开始加上:
#coding: utf-8
dsr = pd.read_csv("./data/dsr.csv", encoding=u'gbk')
2.HDF5文件格式的文件读取和存储
HDF5文件的读取和存储需要指定一个键,值为要存储的DataFrame。
- 读取使用:
pandas.read_hdf(path_or_buf,key =None,** kwargs)
- path_or_buffer:文件路径
- key:读取的键
- return:Theselected object
- 存储使用
DataFrame.to_hdf(path_or_buf, key, *kwargs)
import pandas as pd
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]},
index=['a', 'b', 'c'])
print(df)
df.to_hdf('data.h5', key='df', mode='w')
df = pd.read_hdf('data.h5',key='df')
3.JSON文件格式的文件读取和存储
- 读取使用:
pandas.read_json(path_or_buf=None, orient=None, typ='frame',lines=False)
:将JSON格式准换成默认的Pandas DataFrame格式。- orient : string,Indication of expected JSON string format.
- 'split' : dict like {index -> [index], columns -> [columns], data -> [values]}
split 将索引总结到索引,列名到列名,数据到数据。将三部分都分开了 - 'records' : list like [{column -> value}, ... , {column -> value}]
records 以columns:values的形式输出 - 'index' : dict like {index -> {column -> value}}
index 以index:{columns:values}...的形式输出 - 'columns' : dict like {column -> {index -> value}},默认该格式
colums 以columns:{index:values}的形式输出 - 'values' : just the values array
values 直接输出值
- 'split' : dict like {index -> [index], columns -> [columns], data -> [values]}
- lines : boolean, default False
按照每行读取json对象 - typ : default ‘frame’, 指定转换成的对象类型series或者dataframe
- orient : string,Indication of expected JSON string format.
- 存储使用:
DataFrame.to_json(path_or_buf=None, orient=None, lines=False)
,将Pandas对象存储为json格式- path_or_buf=None:文件地址
- orient:存储的json形式,
- lines:一个对象存储为一行
import pandas as pd
df = pd.DataFrame([['a', 'b'], ['c', 'd']],
index=['row 1', 'row 2'],
columns=['col 1', 'col 2'])
df.to_json("test.json",orient='split')
# col 1 col 2
# row 1 a b
# row 2 c d
print(df)
pd.read_json("test.json", orient='split')
10.缺失值处理
- 缺失值使用NaN标记
- 判断数据中是否包含NaN
- pd.isnull(df),
- pd.notnull(df)
# 判断缺失值结合numpy中的any和all函数 np.any(pd.isnull(movie)) # 里面如果有一个缺失值,就返回True np.all(pd.notnull(movie)) # 里面如果有一个缺失值,就返回False
- 删除存在的缺失值:使用
dropna(axis='rows')
,该函数不会修改原数据,需要接收返回值。 - 替换缺失值:使用
fillna(value,inplace=True)
- value:替换成的值
- inplace:True:会修改原数据,False:不替换修改原数据,生成新的对象
- 判断数据中是否包含NaN
- 缺失值不使用NaN标记,比如使用?,则将?替换为
numpy.NaN
。使用df.replace(to_replace=, value=)
函数- to_replace:替换前的值
- value:替换后的值`
import pandas as pd
import numpy as np
wis = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data")
# 把一些其它值(这里是?)标记的缺失值,替换成np.nan
wis = wis.replace(to_replace='?', value=np.nan)
# 删除缺失值
wis = wis.dropna()
wis
11.数据离散化
- 数据的离散化:连续属性的离散化就是在连续属性的值域上,将值域划分为若干个离散的区间,最后用不同的符号或整数 值代表落在每个子区间中的属性值。
- 对数据进行分组使用
pd.qcut(data,q)
函数,一般会和value_counts函数搭配使用,统计每组的个数 - series.value_counts():统计分组中的次数
// 对age进行离散化 import pandas as pd data = pd.read_csv("./adult.data.csv") age = data['age'] # 分为三组 age = pd.qcut(age, 3) print(age) # 计算分到每个组的数据个数 age.value_counts()
3. 自定义分组使用pd.cut(data,bins)
函数import pandas as pd data = pd.read_csv("./adult.data.csv") age = data['age'] # 自己指定分组区间 bins = [18,30,60,100] age = pd.cut(age, bins=bins) print(age) # 计算分到每个组的数据个数 age.value_counts()
- 对数据进行分组使用
- one-hot编码:把每个类别生成一个布尔列,这些列中只有一列可以为这个样本取值为1.其又被称为热编码。
- 使用
pandas.get_dummies(data, prefix=None)
函数- data:array-like, Series, or DataFrame
- prefix:分组名字
- 使用
import pandas as pd
data = pd.read_csv("./adult.data.csv")
age = data['age']
# 自己指定分组区间
bins = [18,30,60,100]
age = pd.cut(age, bins=bins)
pd.get_dummies(age)
# 使用prefix的效果
pd.get_dummies(age,prefix="年龄段")
12.合并
数据由多张表组成,那么有时候需要将不同的内容合并在一起分析。
13.交叉表和透视表
14.分组和聚合
- 分组使用
DataFrame.groupby(key, as_index=False)
函数。- key:分组的列数据,可以多个
- as_index:是否进行索引
import pandas as pd
col =pd.DataFrame({'color': ['white','red','green','red','green'], 'object': ['pen','pencil','pencil','ashtray','pen'],'price1':[5.56,4.20,1.30,0.56,2.75],'price2':[4.75,4.12,1.60,0.75,3.15]})
# 进行分组,对颜色分组,price进行聚合
col.groupby(['color'])['price1'].mean()
col['price1'].groupby(col['color']).mean()