Pandas之:Pandas简洁教程

简介

pandas是建立在Python编程语言之上的一种快速,强大,灵活且易于使用的开源数据分析和处理工具,它含有使数据清洗和分析⼯

作变得更快更简单的数据结构和操作⼯具。pandas经常和其它⼯具⼀同使⽤,如数值计算⼯具NumPy和SciPy,分析库statsmodels和scikit-learn,和数据可视化库matplotlib等。

pandas是基于NumPy数组构建的,虽然pandas采⽤了⼤量的NumPy编码⻛格,但⼆者最⼤的不同是pandas是专⻔为处理表格和混杂数据设计的。⽽NumPy更适合处理统⼀的数值数组数据。

本文是关于Pandas的简洁教程。

对象创建

因为Pandas是基于NumPy数组来构建的,所以我们在引用的时候需要同时引用Pandas和NumPy:

In [1]: import numpy as np

In [2]: import pandas as pd

Pandas中最主要的两个数据结构是Series和DataFrame。

Series和一维数组很相似,它是由NumPy的各种数据类型来组成的,同时还包含了和这组数据相关的index。

我们来看一个Series的例子:

In [3]: pd.Series([1, 3, 5, 6, 8])
Out[3]:
0 1
1 3
2 5
3 6
4 8
dtype: int64

左边的是索引,右边的是值。因为我们在创建Series的时候并没有指定index,所以index是从0开始到n-1结束。

Series在创建的时候还可以传入np.nan表示空值:

In [4]: pd.Series([1, 3, 5, np.nan, 6, 8])
Out[4]:
0 1.0
1 3.0
2 5.0
3 NaN
4 6.0
5 8.0
dtype: float64

DataFrame是⼀个表格型的数据结构,它含有⼀组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)。

DataFrame既有⾏索引也有列索引,它可以被看做由Series组成的字典(共⽤同⼀个索引)。

看一个创建DataFrame的例子:

In [5]: dates = pd.date_range('20201201', periods=6)

In [6]: dates
Out[6]:
DatetimeIndex(['2020-12-01', '2020-12-02', '2020-12-03', '2020-12-04',
'2020-12-05', '2020-12-06'],
dtype='datetime64[ns]', freq='D')

上面我们创建了一个index的list。

然后使用这个index来创建一个DataFrame:

In [7]:  pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD'))
Out[7]:
A B C D
2020-12-01 1.536312 -0.318095 -0.737956 0.143352
2020-12-02 1.325221 0.065641 -2.763370 -0.130511
2020-12-03 -1.143560 -0.805807 0.174722 0.427027
2020-12-04 -0.724206 0.050155 -0.648675 -0.645166
2020-12-05 0.182411 0.956385 0.349465 -0.484040
2020-12-06 1.857108 1.245928 -0.767316 -1.890586

上面的DataFrame接收三个参数,第一个参数是DataFrame的表格数据,第二个参数是index的值,也可以看做是行名,第三个参数是列名。

还可以直接传入一个字典来创建一个DataFrame:

In [9]: pd.DataFrame({'A': 1.,
...: 'B': pd.Timestamp('20201202'),
...: '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'})
...:
Out[9]:
A B C D E F
0 1.0 2020-12-02 1.0 3 test foo
1 1.0 2020-12-02 1.0 3 train foo
2 1.0 2020-12-02 1.0 3 test foo
3 1.0 2020-12-02 1.0 3 train foo

上面的DataFrame中,每个列都有不同的数据类型。

我们用个图片来更好的理解DataFrame和Series:

它就像是Excel中的表格,带有行头和列头。

DataFrame中的每一列都可以看做是一个Series:

查看数据

创建好Series和DataFrame之后,我们就可以查看他们的数据了。

Series可以通过index和values来获取其索引和值信息:

In [10]: data1 = pd.Series([1, 3, 5, np.nan, 6, 8])

In [12]: data1.index
Out[12]: RangeIndex(start=0, stop=6, step=1) In [14]: data1.values
Out[14]: array([ 1., 3., 5., nan, 6., 8.])

DataFrame可以看做是Series的集合,所以DataFrame带有更多的属性:

In [16]: df.head()
Out[16]:
A B C D
2020-12-01 0.446248 -0.060549 -0.445665 -1.392502
2020-12-02 -1.119749 -1.659776 -0.618656 1.971599
2020-12-03 0.610846 0.216937 0.821258 0.805818
2020-12-04 0.490105 0.732421 0.547129 -0.443274
2020-12-05 -0.475531 -0.853141 0.160017 0.986973 In [17]: df.tail(3)
Out[17]:
A B C D
2020-12-04 0.490105 0.732421 0.547129 -0.443274
2020-12-05 -0.475531 -0.853141 0.160017 0.986973
2020-12-06 0.288091 -2.164323 0.193989 -0.197923

head跟tail分别取得DataFrame的头几行和尾部几行。

同样的DataFrame也有index和columns:

In [19]: df.index
Out[19]:
DatetimeIndex(['2020-12-01', '2020-12-02', '2020-12-03', '2020-12-04',
'2020-12-05', '2020-12-06'],
dtype='datetime64[ns]', freq='D') In [20]: df.values
Out[20]:
array([[ 0.44624818, -0.0605494 , -0.44566462, -1.39250227],
[-1.11974917, -1.65977552, -0.61865617, 1.97159943],
[ 0.61084596, 0.2169369 , 0.82125808, 0.80581847],
[ 0.49010504, 0.73242082, 0.54712889, -0.44327351],
[-0.47553134, -0.85314134, 0.16001748, 0.98697257],
[ 0.28809148, -2.16432292, 0.19398863, -0.19792266]])

describe方法可以对数据进行统计:

In [26]: df.describe()
Out[26]:
A B C D
count 6.000000 6.000000 6.000000 6.000000
mean 0.040002 -0.631405 0.109679 0.288449
std 0.687872 1.128019 0.556099 1.198847
min -1.119749 -2.164323 -0.618656 -1.392502
25% -0.284626 -1.458117 -0.294244 -0.381936
50% 0.367170 -0.456845 0.177003 0.303948
75% 0.479141 0.147565 0.458844 0.941684
max 0.610846 0.732421 0.821258 1.971599

还可以对DataFrame进行转置:

In [27]: df.T
Out[27]:
2020-12-01 2020-12-02 2020-12-03 2020-12-04 2020-12-05 2020-12-06
A 0.446248 -1.119749 0.610846 0.490105 -0.475531 0.288091
B -0.060549 -1.659776 0.216937 0.732421 -0.853141 -2.164323
C -0.445665 -0.618656 0.821258 0.547129 0.160017 0.193989
D -1.392502 1.971599 0.805818 -0.443274 0.986973 -0.197923

可以按行和按列进行排序:

In [28]: df.sort_index(axis=1, ascending=False)
Out[28]:
D C B A
2020-12-01 -1.392502 -0.445665 -0.060549 0.446248
2020-12-02 1.971599 -0.618656 -1.659776 -1.119749
2020-12-03 0.805818 0.821258 0.216937 0.610846
2020-12-04 -0.443274 0.547129 0.732421 0.490105
2020-12-05 0.986973 0.160017 -0.853141 -0.475531
2020-12-06 -0.197923 0.193989 -2.164323 0.288091 In [29]: df.sort_values(by='B')
Out[29]:
A B C D
2020-12-06 0.288091 -2.164323 0.193989 -0.197923
2020-12-02 -1.119749 -1.659776 -0.618656 1.971599
2020-12-05 -0.475531 -0.853141 0.160017 0.986973
2020-12-01 0.446248 -0.060549 -0.445665 -1.392502
2020-12-03 0.610846 0.216937 0.821258 0.805818
2020-12-04 0.490105 0.732421 0.547129 -0.443274

选择数据

通过DataFrame的列名,可以选择代表列的Series:

In [30]: df['A']
Out[30]:
2020-12-01 0.446248
2020-12-02 -1.119749
2020-12-03 0.610846
2020-12-04 0.490105
2020-12-05 -0.475531
2020-12-06 0.288091
Freq: D, Name: A, dtype: float64

通过切片可以选择行:

In [31]: df[0:3]
Out[31]:
A B C D
2020-12-01 0.446248 -0.060549 -0.445665 -1.392502
2020-12-02 -1.119749 -1.659776 -0.618656 1.971599
2020-12-03 0.610846 0.216937 0.821258 0.805818

或者这样:

In [32]: df['20201202':'20201204']
Out[32]:
A B C D
2020-12-02 -1.119749 -1.659776 -0.618656 1.971599
2020-12-03 0.610846 0.216937 0.821258 0.805818
2020-12-04 0.490105 0.732421 0.547129 -0.443274

loc和iloc

使用loc可以使用轴标签来选取数据。

In [33]: df.loc[:, ['A', 'B']]
Out[33]:
A B
2020-12-01 0.446248 -0.060549
2020-12-02 -1.119749 -1.659776
2020-12-03 0.610846 0.216937
2020-12-04 0.490105 0.732421
2020-12-05 -0.475531 -0.853141
2020-12-06 0.288091 -2.164323

前面是行的选择,后面是列的选择。

还可以指定index的名字:

In [34]: df.loc['20201202':'20201204', ['A', 'B']]
Out[34]:
A B
2020-12-02 -1.119749 -1.659776
2020-12-03 0.610846 0.216937
2020-12-04 0.490105 0.732421

如果index的名字不是切片的话,将会给数据降维:

In [35]: df.loc['20201202', ['A', 'B']]
Out[35]:
A -1.119749
B -1.659776
Name: 2020-12-02 00:00:00, dtype: float64

如果后面列是一个常量的话,直接返回对应的值:

In [37]: df.loc['20201202', 'A']
Out[37]: -1.1197491665145112

iloc是根据值来选取数据,比如我们选择第三行:

In [42]: df.iloc[3]
Out[42]:
A 0.490105
B 0.732421
C 0.547129
D -0.443274
Name: 2020-12-04 00:00:00, dtype: float64

它其实和df.loc['2020-12-04']是等价的:

In [41]: df.loc['2020-12-04']
Out[41]:
A 0.490105
B 0.732421
C 0.547129
D -0.443274
Name: 2020-12-04 00:00:00, dtype: float64

同样可以传入切片:

In [43]: df.iloc[3:5, 0:2]
Out[43]:
A B
2020-12-04 0.490105 0.732421
2020-12-05 -0.475531 -0.853141

可以传入list:

In [44]: df.iloc[[1, 2, 4], [0, 2]]
Out[44]:
A C
2020-12-02 -1.119749 -0.618656
2020-12-03 0.610846 0.821258
2020-12-05 -0.475531 0.160017

取具体某个格子的值:

In [45]: df.iloc[1, 1]
Out[45]: -1.6597755161871708

布尔索引

DataFrame还可以通过布尔值来进行索引,下面是找出列A中所有元素大于0的:

In [46]: df[df['A'] > 0]
Out[46]:
A B C D
2020-12-01 0.446248 -0.060549 -0.445665 -1.392502
2020-12-03 0.610846 0.216937 0.821258 0.805818
2020-12-04 0.490105 0.732421 0.547129 -0.443274
2020-12-06 0.288091 -2.164323 0.193989 -0.197923

或者找出整个DF中,值大于0的:

In [47]: df[df > 0]
Out[47]:
A B C D
2020-12-01 0.446248 NaN NaN NaN
2020-12-02 NaN NaN NaN 1.971599
2020-12-03 0.610846 0.216937 0.821258 0.805818
2020-12-04 0.490105 0.732421 0.547129 NaN
2020-12-05 NaN NaN 0.160017 0.986973
2020-12-06 0.288091 NaN 0.193989 NaN

可以给DF添加一列:

In [48]: df['E'] = ['one', 'one', 'two', 'three', 'four', 'three']

In [49]: df
Out[49]:
A B C D E
2020-12-01 0.446248 -0.060549 -0.445665 -1.392502 one
2020-12-02 -1.119749 -1.659776 -0.618656 1.971599 one
2020-12-03 0.610846 0.216937 0.821258 0.805818 two
2020-12-04 0.490105 0.732421 0.547129 -0.443274 three
2020-12-05 -0.475531 -0.853141 0.160017 0.986973 four
2020-12-06 0.288091 -2.164323 0.193989 -0.197923 three

使用isin()来进行范围值的判断判断:

In [50]: df[df['E'].isin(['two', 'four'])]
Out[50]:
A B C D E
2020-12-03 0.610846 0.216937 0.821258 0.805818 two
2020-12-05 -0.475531 -0.853141 0.160017 0.986973 four

处理缺失数据

现在我们的df有a,b,c,d,e这5列,如果我们再给他加一列f,那么f的初始值将会是NaN:

In [55]: df.reindex(columns=list(df.columns) + ['F'])
Out[55]:
A B C D E F
2020-12-01 0.446248 -0.060549 -0.445665 -1.392502 one NaN
2020-12-02 -1.119749 -1.659776 -0.618656 1.971599 one NaN
2020-12-03 0.610846 0.216937 0.821258 0.805818 two NaN
2020-12-04 0.490105 0.732421 0.547129 -0.443274 three NaN
2020-12-05 -0.475531 -0.853141 0.160017 0.986973 four NaN
2020-12-06 0.288091 -2.164323 0.193989 -0.197923 three NaN

我们给前面的两个F赋值:

In [74]: df1.iloc[0:2,5]=1

In [75]: df1
Out[75]:
A B C D E F
2020-12-01 0.446248 -0.060549 -0.445665 -1.392502 one 1.0
2020-12-02 -1.119749 -1.659776 -0.618656 1.971599 one 1.0
2020-12-03 0.610846 0.216937 0.821258 0.805818 two NaN
2020-12-04 0.490105 0.732421 0.547129 -0.443274 three NaN
2020-12-05 -0.475531 -0.853141 0.160017 0.986973 four NaN
2020-12-06 0.288091 -2.164323 0.193989 -0.197923 three NaN

可以drop所有为NaN的行:

In [76]: df1.dropna(how='any')
Out[76]:
A B C D E F
2020-12-01 0.446248 -0.060549 -0.445665 -1.392502 one 1.0
2020-12-02 -1.119749 -1.659776 -0.618656 1.971599 one 1.0

可以填充NaN的值:

In [77]: df1.fillna(value=5)
Out[77]:
A B C D E F
2020-12-01 0.446248 -0.060549 -0.445665 -1.392502 one 1.0
2020-12-02 -1.119749 -1.659776 -0.618656 1.971599 one 1.0
2020-12-03 0.610846 0.216937 0.821258 0.805818 two 5.0
2020-12-04 0.490105 0.732421 0.547129 -0.443274 three 5.0
2020-12-05 -0.475531 -0.853141 0.160017 0.986973 four 5.0
2020-12-06 0.288091 -2.164323 0.193989 -0.197923 three 5.0

可以对值进行判断:

In [78]:  pd.isna(df1)
Out[78]:
A B C D E F
2020-12-01 False False False False False False
2020-12-02 False False False False False False
2020-12-03 False False False False False True
2020-12-04 False False False False False True
2020-12-05 False False False False False True
2020-12-06 False False False False False True

合并

DF可以使用Concat来合并多个df,我们先创建一个df:

In [79]: df = pd.DataFrame(np.random.randn(10, 4))

In [80]: df
Out[80]:
0 1 2 3
0 1.089041 2.010142 -0.532527 0.991669
1 1.303678 -0.614206 -1.358952 0.006290
2 -2.663938 0.600209 -0.008845 -0.036900
3 0.863718 -0.450501 1.325427 0.417345
4 0.789239 -0.492630 0.873732 0.375941
5 0.327177 0.010719 -0.085967 -0.591267
6 -0.014350 1.372144 -0.688845 0.422701
7 -3.355685 0.044306 -0.979253 -2.184240
8 -0.051961 0.649734 1.156918 -0.233725
9 -0.692530 0.057805 -0.030565 0.209416

然后把DF拆成三部分:

In [81]: pieces = [df[:3], df[3:7], df[7:]]

最后把使用concat把他们合起来:

In [82]: pd.concat(pieces)
Out[82]:
0 1 2 3
0 1.089041 2.010142 -0.532527 0.991669
1 1.303678 -0.614206 -1.358952 0.006290
2 -2.663938 0.600209 -0.008845 -0.036900
3 0.863718 -0.450501 1.325427 0.417345
4 0.789239 -0.492630 0.873732 0.375941
5 0.327177 0.010719 -0.085967 -0.591267
6 -0.014350 1.372144 -0.688845 0.422701
7 -3.355685 0.044306 -0.979253 -2.184240
8 -0.051961 0.649734 1.156918 -0.233725
9 -0.692530 0.057805 -0.030565 0.209416

还可以使用join来进行类似SQL的合并:

In [83]: left = pd.DataFrame({'key': ['foo', 'foo'], 'lval': [1, 2]})

In [84]: right = pd.DataFrame({'key': ['foo', 'foo'], 'rval': [4, 5]})

In [85]: left
Out[85]:
key lval
0 foo 1
1 foo 2 In [86]: right
Out[86]:
key rval
0 foo 4
1 foo 5 In [87]: pd.merge(left, right, on='key')
Out[87]:
key lval rval
0 foo 1 4
1 foo 1 5
2 foo 2 4
3 foo 2 5

分组

先看上面的DF:

In [99]: df2
Out[99]:
key lval rval
0 foo 1 4
1 foo 1 5
2 foo 2 4
3 foo 2 5

我们可以根据key来进行group,从而进行sum:

In [98]: df2.groupby('key').sum()
Out[98]:
lval rval
key
foo 6 18

group还可以按多个列进行:

In [100]: df2.groupby(['key','lval']).sum()
Out[100]:
rval
key lval
foo 1 9
2 9

本文已收录于 http://www.flydean.com/01-python-pandas-overview/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

Pandas之:Pandas简洁教程的更多相关文章

  1. Pandas之:Pandas高级教程以铁达尼号真实数据为例

    Pandas之:Pandas高级教程以铁达尼号真实数据为例 目录 简介 读写文件 DF的选择 选择列数据 选择行数据 同时选择行和列 使用plots作图 使用现有的列创建新的列 进行统计 DF重组 简 ...

  2. pandas数组(pandas Series)-(4)NaN的处理

    上一篇pandas数组(pandas Series)-(3)向量化运算里说到,将两个 pandas Series 进行向量化运算的时候,如果某个 key 索引只在其中一个 Series 里出现,计算的 ...

  3. pandas数组(pandas Series)-(1)

    导入pandas import pandas as pd countries = ['Albania', 'Algeria', 'Andorra', 'Angola', 'Antigua and Ba ...

  4. [Pandas]利用Pandas处理excel数据

    Python 处理excel的第三包有很多,比如XlsxWriter.xlrd&xlwt.OpenPyXL.Microsoft Excel API等,最后综合考虑选用了Pandas. Pand ...

  5. pandas | 使用pandas进行数据处理——Series篇

    本文始发于个人公众号:TechFlow,原创不易,求个关注 上周我们关于Python中科学计算库Numpy的介绍就结束了,今天我们开始介绍一个新的常用的计算工具库,它就是大名鼎鼎的Pandas. Pa ...

  6. pandas数组(pandas Series)-(5)apply方法自定义函数

    有时候需要对 pandas Series 里的值进行一些操作,但是没有内置函数,这时候可以自己写一个函数,使用 pandas Series 的 apply 方法,可以对里面的每个值都调用这个函数,然后 ...

  7. pandas数组(pandas Series)-(3)向量化运算

    这篇介绍下有index索引的pandas Series是如何进行向量化运算的: 1. index索引数组相同: s1 = pd.Series([1, 2, 3, 4], index=['a', 'b' ...

  8. pandas数组(pandas Series)-(2)

    pandas Series 比 numpy array 要强大很多,体现在很多方面 首先, pandas Series 有一些方法,比如: describe 方法可以给出 Series 的一些分析数据 ...

  9. 【pandas】pandas.to_datatime()---时间格式转换

    标准时间格式:2012-12-21 时间转换函数:pandas.to_datatime() # -*- coding: utf- -*- # 生成数据 import pandas as pd data ...

随机推荐

  1. G - Number Transformation(BFS+素数)

    In this problem, you are given an integer number s. You can transform any integer number A to anothe ...

  2. 1-OSI七层模型

    网络功能:数据传输 ISO(国际标准化组织) OSI七层模型---->网络通信工作流程的标准化 OSI七层模型 应用层:提供用户服务,具体功能由特定的程序而定. 表示层:数据的压缩优化,加密. ...

  3. PHP laravel系列之Blade模版

    一.什么是Blade模版? Blade 是 Laravel 提供的一个既简单又强大的模板引擎. 和其他流行的 PHP 模板引擎不一样,Blade 并不限制你在视图中使用原生 PHP 代码.所有 Bla ...

  4. UVA11019KMP(二维矩阵匹配出现次数)

    题意:     给你两个矩阵,一个大的一个小的,然后问你这个小矩阵在大的矩阵里出现了多少次? 思路:       说好了AC自动机的,我自己尝试写了个暴力的KMP竟然过了,AC自动机自己的模板还没写完 ...

  5. HTTP协议之分块传输与分段编码

    目录 数据的分块传输 数据的分段编码(transfer-encoding) 前置知识:HTTP协议 数据的分块传输 我们都知道http协议是由TCP协议封装而来的应用层协议.我们和服务器之间的每次ht ...

  6. W32Dasm缓冲区溢出分析【转载】

    课程简介 在上次课程中与大家一起学习了编写通用的Shellcode,也提到会用一个实例来展示Shellcode的溢出. 那么本次课程中为大家准备了W32Dasm这款软件,并且是存在漏洞的版本.利用它的 ...

  7. Android 面试必备 - 系统、App、Activity 启动过程“一锅端”

    Android 系统启动过程 从系统层看: linux 系统层 Android系统服务层 Zygote 从开机启动到Home Launcher: 启动bootloader (小程序:初始化硬件) 加载 ...

  8. 解决客户端Redis中文乱码问题

    启动客户端的时候添加 --raw 选项即可 wangyulong@code-local:~$ redis-cli 127.0.0.1:6379> set key1 '上海' OK 127.0.0 ...

  9. 『居善地』接口测试 — 3、Requests库介绍

    目录 1.Requests库 2.Requests库文档 3.Requests库安装 4.Requests库的使用 (1)使用步骤 (2)示例练习 5.补充:Json数据和Python对象互相转化 1 ...

  10. Class和ClassLoader的getResource方法对比

    最近在看写Spring的源代码,里面有好多地方都用到了Class和ClassLoader类的getResource方法来加载资源文件.之前对这两个类的这个方法一知半解,概念也很模糊,这边做下整理,加深 ...