侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Python科学计算之Pandas详解

Python  /  管理员 发布于 7年前   179

起步

Pandas最初被作为金融数据分析工具而开发出来,因此 pandas 为时间序列分析提供了很好的支持。 Pandas 的名称来自于面板数据(panel data)和python数据分析 (data analysis) 。panel data是经济学中关于多维数据集的一个术语,在Pandas中也提供了panel的数据类型。

在我看来,对于 Numpy 以及 Matplotlib ,Pandas可以帮助创建一个非常牢固的用于数据挖掘与分析的基础。而Scipy当然是另一个主要的也十分出色的科学计算库。

安装与导入

通过pip进行安装: pip install pandas

导入:

import pandas as pd

Pandas的数据类型

Pandas基于两种数据类型: series 与 dataframe 。

Series

一个series是一个一维的数据类型,其中每一个元素都有一个标签。类似于Numpy中元素带标签的数组。其中,标签可以是数字或者字符串。

# coding: utf-8import numpy as npimport pandas as pds = pd.Series([1, 2, 5, np.nan, 6, 8])print s

输出:

0 1.01 2.02 5.03 NaN4 6.05 8.0dtype: float64

DataFrame

一个dataframe是一个二维的表结构。Pandas的dataframe可以存储许多种不同的数据类型,并且每一个坐标轴都有自己的标签。你可以把它想象成一个series的字典项。

创建一个 DateFrame:

#创建日期索引序列 dates = pd.date_range('20130101', periods=6)#创建Dataframe,其中 index 决定索引序列,columns 决定列名df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD'))print df

输出:

   A  B  C  D2013-01-01 -0.334482 0.746019 -2.205026 -0.8038782013-01-02 2.007879 1.559073 -0.527997 0.9509462013-01-03 -1.053796 0.438214 -0.027664 0.0185372013-01-04 -0.208744 -0.725155 -0.395226 -0.2685292013-01-05 0.080822 -1.215433 -0.785030 0.9776542013-01-06 -0.126459 0.426328 -0.474553 -1.968056

字典创建 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' })

输出:

 A  B C D E F0 1 2013-01-02 1 3 test foo1 1 2013-01-02 1 3 train foo2 1 2013-01-02 1 3 test foo3 1 2013-01-02 1 3 train foo

将文件数据导入Pandas

df = pd.read_csv("Average_Daily_Traffic_Counts.csv", header = 0)df.head()

数据源可以是 英国政府数据 或 美国政府数据 来获取数据源。当然, Kaggle 是另一个好用的数据源。

选择/切片

# 选择单独的一列,返回 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)

观察操作

# 观察开头的数据df.head()# 观察末尾的数据df.tail(3)# 显示索引df.index# 显示列df.columns# 显示底层 numpy 结构df.values# DataFrame 的基本统计学属性预览df.describe()"""  A  B  C  Dcount 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')

统计

# 求平均值df.mean()"""A -0.004474B -0.383981C -0.687758D 5.000000F 3.000000dtype: float64"""# 指定轴上的平均值df.mean(1)# 不同维度的 pandas 对象也可以做运算,它会自动进行对应,shift 用来做对齐操作。s = pd.Series([1,3,5,np.nan,6,8], index=dates).shift(2)"""2013-01-01 NaN2013-01-02 NaN2013-01-03 12013-01-04 32013-01-05 52013-01-06 NaNFreq: D, dtype: float64"""# 对不同维度的 pandas 对象进行减法操作df.sub(s, axis='index')"""   A  B  C D F2013-01-01 NaN NaN NaN NaN NaN2013-01-02 NaN NaN NaN NaN NaN2013-01-03 -1.861849 -3.104569 -1.494929 4 12013-01-04 -2.278445 -3.706771 -4.039575 2 02013-01-05 -5.424972 -4.432980 -4.723768 0 -12013-01-06 NaN NaN NaN NaN NaN"""

函数应用

# 累加df.apply(np.cumsum)

直方图

s = pd.Series(np.random.randint(0, 7, size=10))s.value_counts()"""4 56 22 21 1dtype: int64String Methods"""

字符处理

s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat'])s.str.lower()"""0 a1 b2 c3 aaba4 baca5 NaN6 caba7 dog8 catdtype: object"""

合并

使用 concat() 连接 pandas 对象:

df = pd.DataFrame(np.random.randn(10, 4))"""  0  1  2  30 -0.548702 1.467327 -1.015962 -0.4830751 1.637550 -1.217659 -0.291519 -1.7455052 -0.263952 0.991460 -0.919069 0.2660463 -0.709661 1.669052 1.037882 -1.7057754 -0.919854 -0.042379 1.247642 -0.0099205 0.290213 0.495767 0.362949 1.5481066 -1.131345 -0.089329 0.337863 -0.9458677 -0.932132 1.956030 0.017587 -0.0166928 -0.575247 0.254161 -1.143704 0.2158979 1.193555 -0.077118 -0.408530 -0.862495"""pieces = [df[:3], df[3:7], df[7:]]pd.concat(pieces)"""  0  1  2  30 -0.548702 1.467327 -1.015962 -0.4830751 1.637550 -1.217659 -0.291519 -1.7455052 -0.263952 0.991460 -0.919069 0.2660463 -0.709661 1.669052 1.037882 -1.7057754 -0.919854 -0.042379 1.247642 -0.0099205 0.290213 0.495767 0.362949 1.5481066 -1.131345 -0.089329 0.337863 -0.9458677 -0.932132 1.956030 0.017587 -0.0166928 -0.575247 0.254161 -1.143704 0.2158979 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 rval0 foo 1 41 foo 1 52 foo 2 43 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)})# 对单个分组应用函数,数据被分成了 bar 组与 foo 组,分别计算总和。df.groupby('A').sum()# 依据多个列分组会构成一个分级索引df.groupby(['A','B']).sum()"""   C  DA B   bar one -1.814470 2.395985 three -0.595447 0.166599 two -0.392670 -0.136473foo one -1.195665 -0.616981 three 1.928123 -1.623033 two 2.414034 1.600434"""

数据透视表

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 fooA B   one A -0.773723 1.418757 B -0.029716 -1.879024 C -1.146178 0.314665three A 1.006160 NaN B NaN -1.035018 C 0.648740 NaNtwo A NaN 0.100900 B -1.170653 NaN C 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 25083Freq: 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.4640002012-03-07 0.2273712012-03-08 -0.4969222012-03-09 0.3063892012-03-10 -2.290613Freq: D, dtype: float64"""ts_utc = ts.tz_localize('UTC')"""2012-03-06 00:00:00+00:00 0.4640002012-03-07 00:00:00+00:00 0.2273712012-03-08 00:00:00+00:00 -0.4969222012-03-09 00:00:00+00:00 0.3063892012-03-10 00:00:00+00:00 -2.290613Freq: 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 a1 b2 b3 a4 a5 eName: grade, dtype: categoryCategories (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  grade5 6   e very bad1 2   b  good2 3   b  good0 1   a very good3 4   a very good4 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能带来一定的帮助,如果有疑问大家可以留言交流。


  • 上一条:
    Python科学计算之NumPy入门教程
    下一条:
    详解Python3中字符串中的数字提取方法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • Laravel 11.15版本发布 - Eloquent Builder中添加的泛型(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客