python数据分析系列教程——Pandas全解
分享一个朋友的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!大家可以看看是否对自己有帮助:点击打开
起步
Pandas最初被作为金融数据分析工具而开发出来,因此 pandas 为时间序列分析提供了很好的支持。 Pandas 的名称来自于面板数据(panel data)和python数据分析 (data analysis) 。panel data是经济学中关于多维数据集的一个术语,在Pandas中也提供了panel的数据类型。
在我看来,对于 Numpy 以及 Matplotlib ,Pandas可以帮助创建一个非常牢固的用于数据挖掘与分析的基础。而Scipy当然是另一个主要的也十分出色的科学计算库。本文使用python3.6来编写代码。
安装与导入
通过pip进行安装: pip install pandas
导入:
import pandas as pd
Pandas的数据类型
Pandas基于两种数据类型: series 与 dataframe 。
Series
一个series是一个一维的数据类型,其中每一个元素都有一个标签。类似于Numpy中元素带标签的数组。其中,标签可以是数字或者字符串。
import numpy as np
import pandas as pd s = pd.Series([1, 2, 5, np.nan, 6, 8])
print(s)
输出:
0 1.0
1 2.0
2 5.0
3 NaN
4 6.0
5 8.0
dtype: float64
DataFrame
一个dataframe是一个二维的表结构。Pandas的dataframe可以存储许多种不同的数据类型,并且每一个坐标轴都有自己的标签。你可以把它想象成一个series的字典项。
创建一个 DateFrame:
#创建日期索引序列
dates =pd.date_range('20130101', periods=6)
print(type(dates))
#创建Dataframe,其中 index 决定索引序列,columns 决定列名
df =pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD'))
print(df)
输出:
<class 'pandas.core.indexes.datetimes.DatetimeIndex'> A B C D
2013-01-01 0.406575 -1.356139 0.188997 -1.308049
2013-01-02 -0.412154 0.123879 0.907458 0.201024
2013-01-03 0.576566 -1.875753 1.967512 -1.044405
2013-01-04 1.116106 -0.796381 0.432589 0.764339
2013-01-05 -1.851676 0.378964 -0.282481 0.296629
2013-01-06 -1.051984 0.960433 -1.313190 -0.093666
字典创建 DataFrame
df2 =pd.DataFrame({'A' : 1., 'B': pd.Timestamp('20130102'), 'C': pd.Series(1,index=list(range(4)),dtype='float32'), 'D': np.array([3]*4,dtype='int32'), 'E': pd.Categorical(["test","train","test","train"]), 'F':'foo' }) print(df2)
输出:
A B C D E F
0 1.0 2013-01-02 1.0 3 test foo
1 1.0 2013-01-02 1.0 3 train foo
2 1.0 2013-01-02 1.0 3 test foo
3 1.0 2013-01-02 1.0 3 train foo
将文件数据导入Pandas
df =pd.read_csv("Average_Daily_Traffic_Counts.csv", header=0)
df.head()
数据源可以是 英国政府数据 或 美国政府数据 来获取数据源。当然, Kaggle 是另一个好用的数据源。
选择/切片
df[‘column_name’] ,df[row_start_index, row_end_index] 选取指定整列数据
df['name'] # 选取一列,成一个series
df[['name']] # 选取一列,成为一个dataframe
df[['name','gender']] #选取多列,多列名字要放在list里
df[0:] #第0行及之后的行,相当于df的全部数据,注意冒号是必须的
df[:2] #第2行之前的数据(不含第2行)
df[0:1] #第0行
df[1:3] #第1行到第2行(不含第3行)
df[-1:] #最后一行
df[-3:-1] #倒数第3行到倒数第1行(不包含最后1行即倒数第1行,这里有点烦躁,因为从前数时从第0行开始,从后数就是-1行开始,毕竟没有-0)
loc,在知道列名字的情况下,df.loc[index,column] 选取指定行,列的数据
# df.loc[index, column_name],选取指定行和列的数据
df.loc[0,'name'] # 'Snow'
df.loc[0:2, ['name','age']] #选取第0行到第2行,name列和age列的数据, 注意这里的行选取是包含下标的。
df.loc[[2,3],['name','age']] #选取指定的第2行和第3行,name和age列的数据
df.loc[df['gender']=='M','name'] #选取gender列是M,name列的数据
df.loc[df['gender']=='M',['name','age']] #选取gender列是M,name和age列的数据
iloc,在column name特别长或者index是时间序列等各种不方便输入的情况下,可以用iloc (i = index), iloc完全用数字来定位 iloc[row_index, column_index]
df.iloc[0,0] #第0行第0列的数据,'Snow'
df.iloc[1,2] #第1行第2列的数据,32
df.iloc[[1,3],0:2] #第1行和第3行,从第0列到第2列(不包含第2列)的数据
df.iloc[1:3,[1,2] #第1行到第3行(不包含第3行),第1列和第2列的数据
索引汇总
pandas的索引函数主要有三种:
loc 标签索引,行和列的名称
iloc 整型索引(绝对位置索引),绝对意义上的几行几列,起始索引为0
ix 是 iloc 和 loc的合体
at是loc的快捷方式
iat是iloc的快捷方式
# 选择单独的一列,返回 Serires,与 df.A 效果相当。
df['A']# 位置切片
df[0:3]# 索引切片
df['20130102':'20130104']# 通过标签选择
df.loc[dates[0]]# 对多个轴同时通过标签进行选择
df.loc[:,['A','B']]# 获得某一个单元的数据
df.loc[dates[0],'A']
# 或者
df.at[dates[0],'A']# 速度更快的做法# 通过位置进行选择
df.iloc[3]# 切片
df.iloc[3:5,0:2]# 列表选择
df.iloc[[1,2,4],[0,2]]# 获得某一个单元的数据
df.iloc[1,1]
# 或者
df.iat[1,1]# 更快的做法# 布尔索引
df[df.A > 0]# 获得大于零的项的数值
df[df > 0]# isin 过滤
df2[df2['E'].isin(['two','four'])]
赋值
# 新增一列,根据索引排列
s1 =pd.Series([1,2,3,4,5,6], index=pd.date_range('20130102', periods=6))
df['F']=s1# 缺省项
# 在 pandas 中使用 np.nan 作为缺省项的值。
df1 =df.reindex(index=dates[0:4], columns=list(df.columns)+['E'])
df1.loc[dates[0]:dates[1],'E']=1# 删除所有带有缺省项的行
df1.dropna(how='any')# 填充缺省项
df1.fillna(value=5)# 获得缺省项的布尔掩码
pd.isnull(df1)
算数运算
两个dataframe 矩阵相加、相减、相乘、相除,会对两个矩阵行索引(包括行索引名称和行索引值)和列索引相同的两个对应元素做运算。
观察操作
# 观察开头的数据
df.head()# 观察末尾的数据
df.tail(3)# 显示索引
df.index# 显示列
df.columns# 显示底层 numpy 结构
df.values# DataFrame 的基本统计学属性预览
df.describe()
"""A B C D
count 6.000000 6.000000 6.000000 6.000000 #数量
mean 0.073711 -0.431125 -0.687758 -0.233103 #平均值
std 0.843157 0.922818 0.779887 0.973118 #标准差
min -0.861849 -2.104569 -1.509059 -1.135632 #最小值
25% -0.611510 -0.600794 -1.368714 -1.076610 #正态分布 25%
50% 0.022070 -0.228039 -0.767252 -0.386188 #正态分布 50%
75% 0.658444 0.041933 -0.034326 0.461706 #正态分布 75%
max 1.212112 0.567020 0.276232 1.071804 #最大值
"""# 转置
df.T# 根据某一轴的索引进行排序
df.sort_index(axis=1, ascending=False)# 根据某一列的数值进行排序
df.sort(columns='B')
统计
count 非NA值的数量
describe 针对Series或各DataFrame列计算汇总统计
min,max 计算最小值和最大值
argmin,argmax 计算能够获取到最小值和最大值的索引位置(整数)
idxmin,idxmax 计算能够获取到最小值和最大值的索引值
quantile 计算样本的分位数(0到 1)
sum 值的总和
mean 值的平均数, a.mean() 默认对每一列的数据求平均值;若加上参数a.mean(1)则对每一行求平均值
media 值的算术中位数(50%分位数)
mad 根据平均值计算平均绝对离差
var 样本值的方差
std 样本值的标准差
skew 样本值的偏度(三阶矩)
kurt 样本值的峰度(四阶矩)
cumsum 样本值的累计和
cummin,cummax 样本值的累计最大值和累计最小
cumprod 样本值的累计积
diff 计算一阶差分(对时间序列很有用)
pct_change 计算百分数变化
# 求平均值
df.mean()
"""
A -0.004474
B -0.383981
C -0.687758
D 5.000000
F 3.000000
dtype: float64
"""# 指定轴上的平均值
df.mean(1)# 不同维度的 pandas 对象也可以做运算,它会自动进行对应,shift 用来做对齐操作。
s = pd.Series([1,3,5,np.nan,6,8], index=dates).shift(2)
"""
2013-01-01NaN
2013-01-02NaN
2013-01-031
2013-01-043
2013-01-055
2013-01-06NaN
Freq: D, dtype: float64
"""# 对不同维度的 pandas 对象进行减法操作
df.sub(s, axis='index')
"""A B C D F
2013-01-01NaN NaN NaN NaN NaN
2013-01-02NaN NaN NaN NaN NaN
2013-01-03-1.861849-3.104569-1.49492941
2013-01-04-2.278445-3.706771-4.03957520
2013-01-05-5.424972-4.432980-4.7237680-1
2013-01-06NaN NaN NaN NaN NaN
"""
函数应用
# 累加
df.apply(np.cumsum)
直方图
s =pd.Series(np.random.randint(0,7, size=10))
s.value_counts()
"""
4 5
6 2
2 2
1 1
dtype: int64
String Methods
"""
字符处理
s =pd.Series(['A','B','C','Aaba','Baca', np.nan,'CABA','dog','cat'])
s.str.lower()
"""
0 a
1 b
2 c
3 aaba
4 baca
5 NaN
6 caba
7 dog
8 cat
dtype: object
"""
合并
使用 concat() 连接 pandas 对象:
df =pd.DataFrame(np.random.randn(10,4))
"""0 1 2 3
0 -0.548702 1.467327 -1.015962 -0.483075
1 1.637550 -1.217659 -0.291519 -1.745505
2 -0.263952 0.991460 -0.919069 0.266046
3 -0.709661 1.669052 1.037882 -1.705775
4 -0.919854 -0.042379 1.247642 -0.009920
5 0.290213 0.495767 0.362949 1.548106
6 -1.131345 -0.089329 0.337863 -0.945867
7 -0.932132 1.956030 0.017587 -0.016692
8 -0.575247 0.254161 -1.143704 0.215897
9 1.193555 -0.077118 -0.408530 -0.862495
"""pieces =[df[:3], df[3:7], df[7:]]
pd.concat(pieces)
"""0 1 2 3
0 -0.548702 1.467327 -1.015962 -0.483075
1 1.637550 -1.217659 -0.291519 -1.745505
2 -0.263952 0.991460 -0.919069 0.266046
3 -0.709661 1.669052 1.037882 -1.705775
4 -0.919854 -0.042379 1.247642 -0.009920
5 0.290213 0.495767 0.362949 1.548106
6 -1.131345 -0.089329 0.337863 -0.945867
7 -0.932132 1.956030 0.017587 -0.016692
8 -0.575247 0.254161 -1.143704 0.215897
9 1.193555 -0.077118 -0.408530 -0.862495
"""
join 合并:
left =pd.DataFrame({'key': ['foo','foo'],'lval': [1,2]})
right =pd.DataFrame({'key': ['foo','foo'],'rval': [4,5]})
pd.merge(left, right, on='key')
"""key lval rval
0 foo 1 4
1 foo 1 5
2 foo 2 4
3 foo 2 5
"""
追加
在 dataframe 数据后追加行
df =pd.DataFrame(np.random.randn(8,4), columns=['A','B','C','D'])
s =df.iloc[3]
df.append(s, ignore_index=True)
分组
分组常常意味着可能包含以下的几种的操作中一个或多个
依据一些标准分离数据
对组单独地应用函数
将结果合并到一个数据结构中
df =pd.DataFrame({'A': ['foo','bar','foo','bar','foo','bar','foo','foo'], 'B': ['one','one','two','three','two','two','one','three'], 'C': np.random.randn(8), 'D': np.random.randn(8)})
print('源数据集:\n',df) df1 = df.groupby('A').sum()
print('A分组:\n',df1) df2 = df.groupby(['A','B']).sum()
print('AB分组:\n',df2)
输出结果
源数据集: A B C D
0 foo one 0.423062 -0.813870
1 bar one -1.058636 -0.943536
2 foo two -0.843569 -0.611338
3 bar three 0.933234 -1.425916
4 foo two -1.145840 0.643593
5 bar two 1.057359 -1.049414
6 foo one -0.387183 1.056451
7 foo three 1.923139 -1.184541
A分组: C D
A
bar 0.931957 -3.418865
foo -0.030391 -0.909705
AB分组: C D
A B
bar one -1.058636 -0.943536 three 0.933234 -1.425916 two 1.057359 -1.049414
foo one 0.035879 0.242581 three 1.923139 -1.184541 two -1.989409 0.032255
分组时,组内运算
代表运算的字符串包括‘sum’、‘mean’、‘min’、‘max’、‘count’
pd3 = pd3.groupby('a').agg('sum').reset_index()
或者自定义函数
# # 或自定义函数不需要参数,则x是serise,如果x有自定参数,则x为DataFrame
def funname(x,name): print(name) print(type(x),'\n',x) return 2 pd3 = pd3.groupby('a').agg(funname,'aaa').reset_index()
数据透视表
df =pd.DataFrame({'A': ['one','one','two','three']*3,'B': ['A','B','C']*4,'C': ['foo','foo','foo','bar','bar','bar']*2,'D': np.random.randn(12),'E': np.random.randn(12)})# 生成数据透视表
pd.pivot_table(df, values='D', index=['A','B'], columns=['C'])
"""
C bar foo
A B
one A -0.773723 1.418757B -0.029716 -1.879024C -1.146178 0.314665
three A 1.006160 NaNB NaN -1.035018C 0.648740 NaN
two A NaN 0.100900B -1.170653 NaNC NaN 0.536826
"""
时间序列
pandas 拥有既简单又强大的频率变换重新采样功能,下面的例子从 1次/秒 转换到了 1次/5分钟:
rng =pd.date_range('1/1/2012', periods=100, freq='S')
ts =pd.Series(np.random.randint(0,500,len(rng)), index=rng)
ts.resample('5Min', how='sum')
"""
2012-01-01 25083
Freq: 5T, dtype: int32
"""# 本地化时区表示
rng =pd.date_range('3/6/2012 00:00', periods=5, freq='D')
ts =pd.Series(np.random.randn(len(rng)), rng)
"""
2012-03-06 0.464000
2012-03-07 0.227371
2012-03-08 -0.496922
2012-03-09 0.306389
2012-03-10 -2.290613
Freq: D, dtype: float64
"""ts_utc =ts.tz_localize('UTC')
"""
2012-03-06 00:00:00+00:00 0.464000
2012-03-07 00:00:00+00:00 0.227371
2012-03-08 00:00:00+00:00 -0.496922
2012-03-09 00:00:00+00:00 0.306389
2012-03-10 00:00:00+00:00 -2.290613
Freq: D, dtype: float64
"""# 转换为周期
ps =ts.to_period()# 转换为时间戳
ps.to_timestamp()
分类
df =pd.DataFrame({"id":[1,2,3,4,5,6],"raw_grade":['a','b','b','a','a','e']})# 将 raw_grades 转换成 Categoricals 类型
df["grade"]=df["raw_grade"].astype("category")
df["grade"]
"""
0 a
1 b
2 b
3 a
4 a
5 e
Name: grade, dtype: category
Categories (3, object): [a, b, e]
"""# 重命名分类
df["grade"]=df["grade"].cat.set_categories(["very bad","bad","medium","good","very good"])# 根据分类的顺序对数据进行排序
df.sort("grade")
"""id raw_grade grade
5 6 e very bad
1 2 b good
2 3 b good
0 1 a very good
3 4 a very good
4 5 a very good
"""
作图
ts =pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts =ts.cumsum()
ts.plot()
数据IO
# 从 csv 文件读取数据
pd.read_csv('foo.csv')# 保存到 csv 文件
df.to_csv('foo.csv')# 读取 excel 文件
pd.read_excel('foo.xlsx','Sheet1', index_col=None, na_values=['NA'])# 保存到 excel 文件
df.to_excel('foo.xlsx', sheet_name='Sheet1')
python | pandas | 移动窗口函数rolling
https://blog.csdn.net/xxzhangx/article/details/76938053
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者使用python能带来一定的帮助,如果有疑问大家可以留言交流。
python数据分析系列教程——Pandas全解相关推荐
- python数据分析系列教程——NumPy全解
速查: 矩阵对象的属性: matrix.T transpose:返回矩阵的转置矩阵 matrix.H hermitian (conjugate) transpose:返回复数矩阵的共轭元素矩阵 mat ...
- python数据分析——pyecharts折线图全解
折线图是排列在工作表的列或行中的数据可以绘制到折线图中.折线图可以显示随时间(根据常用比例设置)而变化的连续数据,因此非常适用于显示在相等时间间隔下数据的趋势. 下面我给大家介绍一下如何用pyecha ...
- python数据挖掘系列教程——PySpider框架应用全解
全栈工程师开发手册 (作者:栾鹏) python教程全解 python数据挖掘系列教程--PySpider框架应用全解. PySpider介绍 pyspider上手更简单,操作更加简便,因为它增加了 ...
- Python 数据分析三剑客之 Pandas(十):数据读写
CSDN 课程推荐:<迈向数据科学家:带你玩转Python数据分析>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python ...
- Python 数据分析三剑客之 Pandas(九):时间序列
CSDN 课程推荐:<迈向数据科学家:带你玩转Python数据分析>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python ...
- Python 数据分析三剑客之 Pandas(八):数据重塑、重复数据处理与数据替换
CSDN 课程推荐:<迈向数据科学家:带你玩转Python数据分析>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python ...
- Python 数据分析三剑客之 Pandas(七):合并数据集
CSDN 课程推荐:<迈向数据科学家:带你玩转Python数据分析>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python ...
- Python 数据分析三剑客之 Pandas(六):GroupBy 数据分裂、应用与合并
CSDN 课程推荐:<迈向数据科学家:带你玩转Python数据分析>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python ...
- Python 数据分析三剑客之 Pandas(五):统计计算与统计描述
CSDN 课程推荐:<迈向数据科学家:带你玩转Python数据分析>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python ...
最新文章
- 数据库初学者_面向初学者的免费6小时数据科学课程
- 使用webpack-dev-server设置反向代理解决前端跨域问题
- intent的startActivityForResult()方法
- 透过水晶球一瞥下一代SOC
- 如何让编码更加的标准
- 专访阿里云域名与网站业务总经理宋瑛桥:域名未来将更加个性化、生态化和规范化...
- 三年Java开发,你连基础的JVM运行时内存布局都忘了
- Python之OS模块进程管理介绍--os.fork()
- 【EIP】以太坊路线图
- Swing 添加超链接 打开页面
- 高质量程序设计指南C++/C试题
- 常用UCI数据集链接,mark
- android车机升级carplay,现代增加支持DIY升级CarPlay,Android Auto的车型
- 省级面板数据(2003-2019)二十:道路长度、面积、用水、污水、废气、保护区等(stata或excel版本)
- css 图片放大1.2倍,什么是二倍图?怎样使用二倍图?
- java输入输出流数组_详解Java中ByteArray字节数组的输入输出流的用法
- KUBUNTU 10.04 的安装与配置详解
- 北大最强扫地僧“韦东奕”爆红全网
- 2023年江苏省赛事网络空间安全理论题库
- 电脑微信linux安装程序,Ubuntu安装Linux网页版微信