这里有新鲜出炉的 Python3 Cookbook 中文版,程序狗速度看过来!
Python 是一种面向对象、解释型计算机程序设计语言,由 Guido van Rossum 于 1989 年底发明,第一个公开发行版发行于 1991 年。Python 语法简洁而清晰,具有丰富和强大的类库。它常被昵称为胶水语言,它能够把用其他语言制作的各种模块(尤其是 C/C++)很轻松地联结在一起。
Pandas 是 python 的一个数据分析包,属于 PyData 项目的一部分。下面这篇文章主要介绍了 Python 中科学计算之 Pandas, 需要的朋友可以参考借鉴,下面来一起学习学习。
起步
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-8
- 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)
- #创建Dataframe,其中 index 决定索引序列,columns 决定列名
- df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD'))
- print df
输出:
- A B C D
- 2013-01-01 -0.334482 0.746019 -2.205026 -0.803878
- 2013-01-02 2.007879 1.559073 -0.527997 0.950946
- 2013-01-03 -1.053796 0.438214 -0.027664 0.018537
- 2013-01-04 -0.208744 -0.725155 -0.395226 -0.268529
- 2013-01-05 0.080822 -1.215433 -0.785030 0.977654
- 2013-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 F
- 0 1 2013-01-02 1 3 test foo
- 1 1 2013-01-02 1 3 train foo
- 2 1 2013-01-02 1 3 test foo
- 3 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 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')
统计
- # 求平均值
- 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-01 NaN
- 2013-01-02 NaN
- 2013-01-03 1
- 2013-01-04 3
- 2013-01-05 5
- 2013-01-06 NaN
- Freq: D, dtype: float64
- """
- # 对不同维度的 pandas 对象进行减法操作
- df.sub(s, axis='index')
- """
- A B C D F
- 2013-01-01 NaN NaN NaN NaN NaN
- 2013-01-02 NaN NaN NaN NaN NaN
- 2013-01-03 -1.861849 -3.104569 -1.494929 4 1
- 2013-01-04 -2.278445 -3.706771 -4.039575 2 0
- 2013-01-05 -5.424972 -4.432980 -4.723768 0 -1
- 2013-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 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)})
- # 对单个分组应用函数,数据被分成了 bar 组与 foo 组,分别计算总和。
- df.groupby('A').sum()
- # 依据多个列分组会构成一个分级索引
- df.groupby(['A','B']).sum()
- """
- C D
- A B
- bar one -1.814470 2.395985
- three -0.595447 0.166599
- two -0.392670 -0.136473
- foo 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 foo
- A B
- one A -0.773723 1.418757
- B -0.029716 -1.879024
- C -1.146178 0.314665
- three A 1.006160 NaN
- B NaN -1.035018
- C 0.648740 NaN
- two 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 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 能带来一定的帮助,如果有疑问大家可以留言交流。
来源: http://www.phperz.com/article/17/0321/320383.html