0%

Python易筋经-pandas

“宠辱若惊,贵大患若身。
何谓宠辱若惊?
宠为下。
得之若惊,失之若惊,是谓宠辱若惊。
何谓贵大患若身?
吾所以有大患者,为吾有身。
及吾无身,吾有何患?
故贵以身为天下,若可以寄于天下,爱以身为天下者,若可托天下。”1

pandas

pandas是基于numpy构建的,让以 Numpy 为中心的应用变得更加简单。
pandas主要有Series(对映一维数组),DataFrame(对映二维数组),Panel(对映三维数组),Panel4D(对映四维数组),PanelND(多维)等数据结构。

  • Series
    一维数组,与Numpy中的一维array类似。二者与Python基本的数据结构List也很相近,其区别是:List中的元素可以是不同的数据类型,而Array和Series中则只允许存储相同的数据类型,这样可以更有效的使用内存,提高运算效率。
  • DataFrame
    二维的表格型数据结构。很多功能与R中的data.frame类似。可以将DataFrame理解为Series的容器。以下的内容主要以DataFrame为主。
  • Panel
    三维的数组,可以理解为DataFrame的容器。

导入包:

1
import numpy as np
2
import pandas as pd

Series

由一组数据(各种Numpy数据类型),以及一组与之相关的标签数据(即索引)组成。仅由一组数据即可产生最简单的Series,可以通过传递一个list对象来创建一个Series。

1
arr = pd.Series([1,3,4,5,6,7,0,4])
2
arr

输出:

1
0    1
2
1    3
3
2    4
4
3    5
5
4    6
6
5    7
7
6    0
8
7    4
9
dtype: int64

获取 Series 的索引:

1
arr.index

输出:

1
RangeIndex(start=0, stop=8, step=1)

DataFrame

DataFrame是一个表格型的数据结构,它含有一组有序的列,每一列的数据结构都是相同的,而不同的列之间则可以是不同的数据结构(数值、字符、布尔值等)。或者以数据库进行类比,DataFrame中的每一行是一个记录,名称为Index的一个元素,而每一列则为一个字段,是这个记录的一个属性。DataFrame既有行索引也有列索引,可以被看做由Series组成的字典(共用同一个索引)。
创建一个DataFrame,包括一个numpy array, 时间索引和列名字:

1
dates = pd.date_range('20180101',periods=6)
2
dates

输出:

1
DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04',
2
               '2018-01-05', '2018-01-06'],
3
              dtype='datetime64[ns]', freq='D')

创建DataFrame,如:

1
df = pd.DataFrame(np.random.randn(6,4),index=dates,columns=list('ABCD'))
2
df

np.random.randn(6,4) 从标准正态分布中创建6行4列的二维矩阵

输出:

1
	        A	        B	        C	        D
2
2018-01-01	-0.538987	-1.173826	1.607785	-1.168397
3
2018-01-02	-0.987674	-0.961643	-0.636837	-0.607176
4
2018-01-03	-1.065446	0.686846	-0.241674	0.296789
5
2018-01-04	0.338885	0.459906	0.852208	1.007623
6
2018-01-05	-0.227588	0.872227	2.077327	0.886460
7
2018-01-06	-0.838204	0.087443	0.537748	1.372528

通过传递一个能够被转换成类似序列结构的字典对象来创建一个DataFrame:

1
df1 = pd.DataFrame({'A':3.,
2
                  'B':pd.date_range('20180101',periods=6),
3
                  'C':np.array([2]*6,dtype='int32'),
4
                  'D':pd.Series(2,index=list(range(6)),dtype='float32')
5
                   })
6
df1

输出:

1
2
    A	B	        C	D
3
0	3.0	2018-01-01	2	2.0
4
1	3.0	2018-01-02	2	2.0
5
2	3.0	2018-01-03	2	2.0
6
3	3.0	2018-01-04	2	2.0
7
4	3.0	2018-01-05	2	2.0
8
5	3.0	2018-01-06	2	2.0

查看不同列的数据类型:

1
df1.dtypes

输出:

1
A           float64
2
B    datetime64[ns]
3
C             int32
4
D           float32
5
dtype: object

DataFrame查看数据

以df为数据蓝本,查看前2条记录:

1
df.head(2)

输出:

1
	        A	        B	        C	        D
2
2018-01-01	-0.538987	-1.173826	1.607785	-1.168397
3
2018-01-02	-0.987674	-0.961643	-0.636837	-0.607176

查看后2条记录:

1
df.tail(2)

输出:

1
	        A	        B	        C	        D
2
2018-01-05	-0.227588	0.872227	2.077327	0.886460
3
2018-01-06	-0.838204	0.087443	0.537748	1.372528

显示索引、列和底层的numpy数据:

1
df.index

输出:

1
DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04',
2
               '2018-01-05', '2018-01-06'],
3
              dtype='datetime64[ns]', freq='D')

查看 DataFrame 的列名

1
df.columns

输出:

1
Index(['A', 'B', 'C', 'D'], dtype='object')

查看 DataFrame 的值:

1
df.values

输出:

1
array([[-0.53898743, -1.17382617,  1.60778544, -1.16839686],
2
       [-0.98767434, -0.96164339, -0.63683738, -0.60717624],
3
       [-1.06544554,  0.68684576, -0.24167378,  0.29678857],
4
       [ 0.33888503,  0.45990635,  0.85220803,  1.0076235 ],
5
       [-0.22758765,  0.87222716,  2.07732729,  0.88645989],
6
       [-0.83820381,  0.08744284,  0.53774757,  1.37252846]])

describe()函数对于数据的快速统计汇总:

1
df.describe()

输出:

1
	   A	    B	        C	         D
2
count	6.000000	6.000000	6.000000	6.000000
3
mean	-0.553169	-0.004841	0.699426	0.297971
4
std	0.535618	0.866508	1.043502	0.997409
5
min	-1.065446	-1.173826	-0.636837	-1.168397
6
25%	-0.950307	-0.699372	-0.046818	-0.381185
7
50%	-0.688596	0.273675	0.694978	0.591624
8
75%	-0.305438	0.630111	1.418891	0.977333
9
max	0.338885	0.872227	2.077327	1.372528

对结果简单解释一下:

count:数量
mean:平均值
std:标准偏差
min:最小值
max:最大值

其中25% 50% 75% 四分位数;即把数值由小到大排列并分成四等份,处于三个分割点位置的数值就是四分位数。
第1四分位数 (Q1),又称“较小四分位数”,等于该样本中所有数值由小到大排列后第25%的数字。
第2四分位数 (Q2),又称“中位数”,等于该样本中所有数值由小到大排列后第50%的数字。
第3四分位数 (Q3),又称“较大四分位数”,等于该样本中所有数值由小到大排列后第75%的数字。
第3四分位数与第1四分位数的差距又称四分位距(InterQuartile Range,IQR)

转置:df.transpose() or .T

1
df.transpose() or df.T

输出:

1
	2018-01-01 00:00:00	2018-01-02 00:00:00	2018-01-03 00:00:00	2018-01-04 00:00:00	2018-01-05 00:00:00	2018-01-06 00:00:00
2
A	-0.538987	-0.987674	-1.065446	0.338885	-0.227588	-0.838204
3
B	-1.173826	-0.961643	0.686846	0.459906	0.872227	0.087443
4
C	1.607785	-0.636837	-0.241674	0.852208	2.077327	0.537748
5
D	-1.168397	-0.607176	0.296789	1.007623	0.886460	1.372528

按值进行排序

1
df.sort_values(by='A',ascending=False)

输出:

1
	        A	        B	        C	        D
2
2018-01-04	0.338885	0.459906	0.852208	1.007623
3
2018-01-05	-0.227588	0.872227	2.077327	0.886460
4
2018-01-01	-0.538987	-1.173826	1.607785	-1.168397
5
2018-01-06	-0.838204	0.087443	0.537748	1.372528
6
2018-01-02	-0.987674	-0.961643	-0.636837	-0.607176
7
2018-01-03	-1.065446	0.686846	-0.241674	0.296789

获取数据

  • 按列获取数据
    1
    df['A']
    输出:
    1
    2018-01-01   -0.538987
    2
    2018-01-02   -0.987674
    3
    2018-01-03   -1.065446
    4
    2018-01-04    0.338885
    5
    2018-01-05   -0.227588
    6
    2018-01-06   -0.838204
    7
    Freq: D, Name: A, dtype: float64
    按列取多列
    1
    df[['A','B']]
    输出:
    1
    	        A	        B
    2
    2018-01-01	-0.538987	-1.173826
    3
    2018-01-02	-0.987674	-0.961643
    4
    2018-01-03	-1.065446	0.686846
    5
    2018-01-04	0.338885	0.459906
    6
    2018-01-05	-0.227588	0.872227
    7
    2018-01-06	-0.838204	0.087443
  • 按行获取数据
    1
    df[:3]
    输出:
    1
    	        A	        B	        C	        D
    2
    2018-01-01	-0.538987	-1.173826	1.607785	-1.168397
    3
    2018-01-02	-0.987674	-0.961643	-0.636837	-0.607176
    4
    2018-01-03	-1.065446	0.686846	-0.241674	0.296789

    貌似等效于df.head(3)

.ix(位置or标签起,位置or标签止)来获取数据,它自动根据给到的索引类型判断是使用位置还是标签进行切片。

1
df.ix['2018-01-01':'2018-01-02']

输出:

1
	        A	        B	        C	        D
2
2018-01-01	-0.538987	-1.173826	1.607785	-1.168397
3
2018-01-02	-0.987674	-0.961643	-0.636837	-0.607176
1
df.ix[1,1]

输出:

1
-0.96164339276293087
1
df.ix[1,'C']

输出:

1
-0.63683738086017361

通过逻辑指针进行数据切片:

df[逻辑条件]
df[df.xxx >= 2] #单个逻辑条件
df[(df.xxx >=1 ) & (df.xxx < 3) ] #多个逻辑条件组合

1
df[df.A>0]

输出:

1
2
            A	        B	        C	        D
3
2018-01-04	0.338885	0.459906	0.852208	1.007623

可以利用逻辑条件进行更改数据

panel (略)

略…..

缺失数据处理

去掉包含缺失值的行

  • df.dropna()
    将有缺失数据行丢弃
  • df.fillna(value=0)
    将缺失项赋值0
  • df.isnull(df)
    判断数据是否为nan,并进行布尔填充

函数的应用和映射

列计算平均值

1
df.mean()

输出:

1
A   -0.553169
2
B   -0.004841
3
C    0.699426
4
D    0.297971
5
dtype: float64

行计算平均值

1
df.mean(1)

输出:

1
2018-01-01   -0.318356
2
2018-01-02   -0.798333
3
2018-01-03   -0.080871
4
2018-01-04    0.664656
5
2018-01-05    0.902107
6
2018-01-06    0.289879
7
Freq: D, dtype: float64

罗列出其他常用的方法:

1
count 非na值的数量
2
3
describe 针对Series或个DataFrame列计算汇总统计
4
5
min、max 计算最小值和最大值
6
7
argmin、argmax 计算能够获取到最大值和最小值得索引位置(整数)
8
9
idxmin、idxmax 计算能够获取到最大值和最小值得索引值
10
11
quantile 计算样本的分位数(01
12
13
sum 值的总和
14
15
mean 值得平均数
16
17
median 值得算术中位数(50%分位数)
18
19
mad 根据平均值计算平均绝对离差
20
21
var 样本值的方差
22
23
std 样本值的标准差
24
25
skew 样本值得偏度(三阶矩)
26
27
kurt 样本值得峰度(四阶矩)
28
29
cumsum 样本值得累计和
30
31
cummin,cummax 样本值得累计最大值和累计最小值
32
33
cumprod 样本值得累计积
34
35
diff 计算一阶差分(对时间序列很有用)
36
37
pct_change 计算百分数变化

数据规整

Pandas提供了大量的方法能够轻松的对Series,DataFrame和Panel对象进行各种符合各种逻辑关系的合并操作

  • concat 可以沿一条轴将多个对象堆叠到一起。
  • append 将一行连接到一个DataFrame上
  • duplicated 移除重复数据

1:老子《道德经》第十三章,老子故里,中国鹿邑。