“宠辱若惊,贵大患若身。
何谓宠辱若惊?
宠为下。
得之若惊,失之若惊,是谓宠辱若惊。
何谓贵大患若身?
吾所以有大患者,为吾有身。
及吾无身,吾有何患?
故贵以身为天下,若可以寄于天下,爱以身为天下者,若可托天下。”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 |
获取数据
- 按列获取数据输出:
1df['A']按列取多列12018-01-01 -0.53898722018-01-02 -0.98767432018-01-03 -1.06544642018-01-04 0.33888552018-01-05 -0.22758862018-01-06 -0.8382047Freq: D, Name: A, dtype: float64输出:1df[['A','B']]1A B22018-01-01 -0.538987 -1.17382632018-01-02 -0.987674 -0.96164342018-01-03 -1.065446 0.68684652018-01-04 0.338885 0.45990662018-01-05 -0.227588 0.87222772018-01-06 -0.838204 0.087443 - 按行获取数据输出:
1df[:3]1A B C D22018-01-01 -0.538987 -1.173826 1.607785 -1.16839732018-01-02 -0.987674 -0.961643 -0.636837 -0.60717642018-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 计算样本的分位数(0到1) |
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:老子《道德经》第十三章,老子故里,中国鹿邑。