导入相关包
import numpy as np
import pandas as pd
导入numpy与pandas的工具包
对象创建
通过series创建
s=pd.Series([1, 3, 5, np.nan, 6, 8])
s
0    1.0
1    3.0
2    5.0
3    NaN
4    6.0
5    8.0
dtype: float64
通过dataframe创建
先创建时间索引
dates=pd.date_range('20130101',periods=6)
dates
Out[6]: 
DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04',
               '2013-01-05', '2013-01-06'],
              dtype='datetime64[ns]', freq='D')
df=pd.DataFrame(np.random.randn(6,4),index=dates,columns=list('ABCD'))
df
| A | B | C | D | |
|---|---|---|---|---|
| 2013-01-01 | 1.586798 | -1.817532 | -1.174984 | 0.399674 | 
| 2013-01-02 | -0.272984 | -0.381050 | 1.547809 | 0.241587 | 
| 2013-01-03 | 0.538715 | 0.214234 | 0.344610 | 0.423814 | 
| 2013-01-04 | 1.950835 | -0.896320 | -1.581542 | 1.538713 | 
| 2013-01-05 | 0.408649 | 0.701028 | -1.964295 | -0.001575 | 
| 2013-01-06 | -1.183035 | -0.773940 | -1.387948 | -0.961777 | 
dataframe通过dict创建
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'})
df2
| A | B | C | D | E | F | |
|---|---|---|---|---|---|---|
| 0 | 1.0 | 2013-01-02 | 1.0 | 3 | test | foo | 
| 1 | 1.0 | 2013-01-02 | 1.0 | 3 | train | foo | 
| 2 | 1.0 | 2013-01-02 | 1.0 | 3 | test | foo | 
| 3 | 1.0 | 2013-01-02 | 1.0 | 3 | train | foo | 
每个列具有不同的dtypes
df2.dtypes
A           float64
B    datetime64[ns]
C           float32
D             int32
E          category
F            object
dtype: object
查看数据
查看数据的顶行和底行:
df.head(3)
Out:
| A | B | C | D | |
|---|---|---|---|---|
| 2013-01-01 | 1.586798 | -1.817532 | -1.174984 | 0.399674 | 
| 2013-01-02 | -0.272984 | -0.381050 | 1.547809 | 0.241587 | 
| 2013-01-03 | 0.538715 | 0.214234 | 0.344610 | 0.423814 | 
df.tail(3)
Out:
| A | B | C | D | |
|---|---|---|---|---|
| 2013-01-04 | 1.950835 | -0.896320 | -1.581542 | 1.538713 | 
| 2013-01-05 | 0.408649 | 0.701028 | -1.964295 | -0.001575 | 
| 2013-01-06 | -1.183035 | -0.773940 | -1.387948 | -0.961777 | 
显示索引与列
df.index
Out:
DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04',
               '2013-01-05', '2013-01-06'],
              dtype='datetime64[ns]', freq='D')
df.columns
Out:
Index(['A', 'B', 'C', 'D'], dtype='object')
显示数据快速统计摘要
df.describe()
Out[21]:
| A | B | C | D | |
|---|---|---|---|---|
| count | 6.000000 | 6.000000 | 6.000000 | 6.000000 | 
| mean | 0.504830 | -0.492263 | -0.702725 | 0.273406 | 
| std | 1.159816 | 0.887062 | 1.357811 | 0.805217 | 
| min | -1.183035 | -1.817532 | -1.964295 | -0.961777 | 
| 25% | -0.102576 | -0.865725 | -1.533143 | 0.059215 | 
| 50% | 0.473682 | -0.577495 | -1.281466 | 0.320630 | 
| 75% | 1.324777 | 0.065413 | -0.035289 | 0.417779 | 
| max | 1.950835 | 0.701028 | 1.547809 | 1.538713 | 
转置数据(行列转换)
df.T
| 2013-01-01 00:00:00 | 2013-01-02 00:00:00 | 2013-01-03 00:00:00 | 2013-01-04 00:00:00 | 2013-01-05 00:00:00 | 2013-01-06 00:00:00 | |
|---|---|---|---|---|---|---|
| A | 1.586798 | -0.272984 | 0.538715 | 1.950835 | 0.408649 | -1.183035 | 
| B | -1.817532 | -0.381050 | 0.214234 | -0.896320 | 0.701028 | -0.773940 | 
| C | -1.174984 | 1.547809 | 0.344610 | -1.581542 | -1.964295 | -1.387948 | 
| D | 0.399674 | 0.241587 | 0.423814 | 1.538713 | -0.001575 | -0.961777 | 
按索引排序
df.sort_index(axis=1,ascending=False)
| D | C | B | A | |
|---|---|---|---|---|
| 2013-01-01 | -1.415859 | 0.357454 | -0.219970 | -0.464958 | 
| 2013-01-02 | -1.363227 | -0.504517 | -0.848231 | -0.349901 | 
| 2013-01-03 | 0.177325 | -1.269695 | 1.289740 | 0.298251 | 
| 2013-01-04 | -0.875406 | -0.099774 | 1.526283 | 0.236369 | 
| 2013-01-05 | -0.715345 | 0.842110 | -1.966019 | -0.703749 | 
| 2013-01-06 | 1.972990 | -1.115897 | 0.440815 | 1.061018 | 
按值排序
df.sort_values(by='B')
| A | B | C | D | |
|---|---|---|---|---|
| 2013-01-05 | -0.703749 | -1.966019 | 0.842110 | -0.715345 | 
| 2013-01-02 | -0.349901 | -0.848231 | -0.504517 | -1.363227 | 
| 2013-01-01 | -0.464958 | -0.219970 | 0.357454 | -1.415859 | 
| 2013-01-06 | 1.061018 | 0.440815 | -1.115897 | 1.972990 | 
| 2013-01-03 | 0.298251 | 1.289740 | -1.269695 | 0.177325 | 
| 2013-01-04 | 0.236369 | 1.526283 | -0.099774 | -0.875406 | 
数据访问
获取
选择一列,获取到一个Series
df['A']
2013-01-01   -0.464958
2013-01-02   -0.349901
2013-01-03    0.298251
2013-01-04    0.236369
2013-01-05   -0.703749
2013-01-06    1.061018
Freq: D, Name: A, dtype: float64
通过[]获取行
df[0:3]
| A | B | C | D | |
|---|---|---|---|---|
| 2013-01-01 | -0.464958 | -0.219970 | 0.357454 | -1.415859 | 
| 2013-01-02 | -0.349901 | -0.848231 | -0.504517 | -1.363227 | 
| 2013-01-03 | 0.298251 | 1.289740 | -1.269695 | 0.177325 | 
df['20130102':'20130104']
| A | B | C | D | |
|---|---|---|---|---|
| 2013-01-02 | -0.349901 | -0.848231 | -0.504517 | -1.363227 | 
| 2013-01-03 | 0.298251 | 1.289740 | -1.269695 | 0.177325 | 
| 2013-01-04 | 0.236369 | 1.526283 | -0.099774 | -0.875406 | 
通过标签选择(loc)
选择第一个日期的数据
df.loc[dates[0]]
A   -0.464958
B   -0.219970
C    0.357454
D   -1.415859
Name: 2013-01-01 00:00:00, dtype: float64
通过标签选择多个维度:
df.loc[:,['A','B']]
| A | B | |
|---|---|---|
| 2013-01-01 | -0.464958 | -0.219970 | 
| 2013-01-02 | -0.349901 | -0.848231 | 
| 2013-01-03 | 0.298251 | 1.289740 | 
| 2013-01-04 | 0.236369 | 1.526283 | 
| 2013-01-05 | -0.703749 | -1.966019 | 
| 2013-01-06 | 1.061018 | 0.440815 | 
显示数据的切片,包含两个端点数据
df.loc['20130102':'20130104', ['A', 'B']]
| A | B | |
|---|---|---|
| 2013-01-02 | -0.349901 | -0.848231 | 
| 2013-01-03 | 0.298251 | 1.289740 | 
| 2013-01-04 | 0.236369 | 1.526283 | 
缩小返回对象的大小
df.loc['20130102', ['A', 'B']]
A   -0.349901
B   -0.848231
Name: 2013-01-02 00:00:00, dtype: float64
获取标量值
df.loc[dates[0],'A']
-0.4649577235434288
快速访问标量
df.at[dates[0], 'A']
-0.4649577235434288
通过位置选择(iloc)
通过传递的整数位置选择
df.iloc[3]
A    0.236369
B    1.526283
C   -0.099774
D   -0.875406
Name: 2013-01-04 00:00:00, dtype: float64
通过整数进行切片,类似于python、numpy
df.iloc[3:5,0:2]
| A | B | |
|---|---|---|
| 2013-01-04 | 0.236369 | 1.526283 | 
| 2013-01-05 | -0.703749 | -1.966019 | 
通过整数位置进行列举,类似于numpy、python
df.iloc[[1,2,4],[0,2]]
| A | C | |
|---|---|---|
| 2013-01-02 | -0.349901 | -0.504517 | 
| 2013-01-03 | 0.298251 | -1.269695 | 
| 2013-01-05 | -0.703749 | 0.842110 | 
对行进行切片
df.iloc[1:3,:]
| A | B | C | D | |
|---|---|---|---|---|
| 2013-01-02 | -0.349901 | -0.848231 | -0.504517 | -1.363227 | 
| 2013-01-03 | 0.298251 | 1.289740 | -1.269695 | 0.177325 | 
对列进行切片
df.iloc[:,1:3]
| B | C | |
|---|---|---|
| 2013-01-01 | -0.219970 | 0.357454 | 
| 2013-01-02 | -0.848231 | -0.504517 | 
| 2013-01-03 | 1.289740 | -1.269695 | 
| 2013-01-04 | 1.526283 | -0.099774 | 
| 2013-01-05 | -1.966019 | 0.842110 | 
| 2013-01-06 | 0.440815 | -1.115897 | 
快速访问标量:
df.iat[1,1]
-0.8482314332197409
布尔值索引
通过判断单列的值选择数据
df[df.A>0]
| A | B | C | D | |
|---|---|---|---|---|
| 2013-01-03 | 0.298251 | 1.289740 | -1.269695 | 0.177325 | 
| 2013-01-04 | 0.236369 | 1.526283 | -0.099774 | -0.875406 | 
| 2013-01-06 | 1.061018 | 0.440815 | -1.115897 | 1.972990 | 
从满足布尔条件的dataframe中选择值
df[df>0]
| A | B | C | D | |
|---|---|---|---|---|
| 2013-01-01 | NaN | NaN | 0.357454 | NaN | 
| 2013-01-02 | NaN | NaN | NaN | NaN | 
| 2013-01-03 | 0.298251 | 1.289740 | NaN | 0.177325 | 
| 2013-01-04 | 0.236369 | 1.526283 | NaN | NaN | 
| 2013-01-05 | NaN | NaN | 0.842110 | NaN | 
| 2013-01-06 | 1.061018 | 0.440815 | NaN | 1.972990 | 
使用isin()方法筛选
df2=df.copy()
df2['E']=['one', 'one', 'two', 'three', 'four', 'three']
df2
| A | B | C | D | E | |
|---|---|---|---|---|---|
| 2013-01-01 | -0.464958 | -0.219970 | 0.357454 | -1.415859 | one | 
| 2013-01-02 | -0.349901 | -0.848231 | -0.504517 | -1.363227 | one | 
| 2013-01-03 | 0.298251 | 1.289740 | -1.269695 | 0.177325 | two | 
| 2013-01-04 | 0.236369 | 1.526283 | -0.099774 | -0.875406 | three | 
| 2013-01-05 | -0.703749 | -1.966019 | 0.842110 | -0.715345 | four | 
| 2013-01-06 | 1.061018 | 0.440815 | -1.115897 | 1.972990 | three | 
df2[df2['E'].isin(['two','four'])]
| A | B | C | D | E | |
|---|---|---|---|---|---|
| 2013-01-03 | 0.298251 | 1.289740 | -1.269695 | 0.177325 | two | 
| 2013-01-05 | -0.703749 | -1.966019 | 0.842110 | -0.715345 | four | 
设置
设置新列自动根据索引更新数据
sl=pd.Series([1,2,3,4,5,6],index=pd.date_range('20130102',periods=6))
sl
2013-01-02    1
2013-01-03    2
2013-01-04    3
2013-01-05    4
2013-01-06    5
2013-01-07    6
Freq: D, dtype: int64
df2=df.copy()
df2[df2>0]=-df2
df2
| A | B | C | D | F | |
|---|---|---|---|---|---|
| 2013-01-01 | 0.000000 | 0.000000 | -0.357454 | -5 | NaN | 
| 2013-01-02 | -0.349901 | -0.848231 | -0.504517 | -5 | -1.0 | 
| 2013-01-03 | -0.298251 | -1.289740 | -1.269695 | -5 | -2.0 | 
| 2013-01-04 | -0.236369 | -1.526283 | -0.099774 | -5 | -3.0 | 
| 2013-01-05 | -0.703749 | -1.966019 | -0.842110 | -5 | -4.0 | 
| 2013-01-06 | -1.061018 | -0.440815 | -1.115897 | -5 | -5.0 | 
缺失数据
pandas使用np.nan表示缺失数据,默认不加入训练。
reindex允许更改、添加、删除指令轴上的索引,返回数据的副本
df1=df.reindex(index=dates[0:4],columns=list(df.columns)+['E'])
df1.loc[dates[0]:dates[1], 'E'] = 1
df1
| A | B | C | D | F | E | |
|---|---|---|---|---|---|---|
| 2013-01-01 | 0.000000 | 0.000000 | 0.357454 | 5 | NaN | 1.0 | 
| 2013-01-02 | -0.349901 | -0.848231 | -0.504517 | 5 | 1.0 | 1.0 | 
| 2013-01-03 | 0.298251 | 1.289740 | -1.269695 | 5 | 2.0 | NaN | 
| 2013-01-04 | 0.236369 | 1.526283 | -0.099774 | 5 | 3.0 | NaN | 
丢弃存在缺失数据的行
df1.dropna(how='any')
| A | B | C | D | F | E | |
|---|---|---|---|---|---|---|
| 2013-01-02 | -0.349901 | -0.848231 | -0.504517 | 5 | 1.0 | 1.0 | 
填充缺失值
df1.fillna(value=5)
| A | B | C | D | F | E | |
|---|---|---|---|---|---|---|
| 2013-01-01 | 0.000000 | 0.000000 | 0.357454 | 5 | 5.0 | 1.0 | 
| 2013-01-02 | -0.349901 | -0.848231 | -0.504517 | 5 | 1.0 | 1.0 | 
| 2013-01-03 | 0.298251 | 1.289740 | -1.269695 | 5 | 2.0 | 5.0 | 
| 2013-01-04 | 0.236369 | 1.526283 | -0.099774 | 5 | 3.0 | 5.0 | 
获取是否为nan值的boolean掩码
pd.isna(df1)
| A | B | C | D | F | E | |
|---|---|---|---|---|---|---|
| 2013-01-01 | False | False | False | False | True | False | 
| 2013-01-02 | False | False | False | False | False | False | 
| 2013-01-03 | False | False | False | False | False | True | 
| 2013-01-04 | False | False | False | False | False | True | 
运算
运算通常不包含缺失值
统计数据
进行描述性统计
df.mean()
A    0.090331
B    0.073765
C   -0.298387
D    5.000000
F    3.000000
dtype: float64
在其他轴上的运算
df.mean(1)
2013-01-01    1.339364
2013-01-02    0.859470
2013-01-03    1.463659
2013-01-04    1.932575
2013-01-05    1.434468
2013-01-06    2.077187
Freq: D, dtype: float64
在不同维度的对象上进行运算,pandas自动进行广播
s=pd.Series([1, 3, 5, np.nan, 6, 8],index=dates).shift(2)
s
2013-01-01    NaN
2013-01-02    NaN
2013-01-03    1.0
2013-01-04    3.0
2013-01-05    5.0
2013-01-06    NaN
Freq: D, dtype: float64
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 | -0.701749 | 0.289740 | -2.269695 | 4.0 | 1.0 | 
| 2013-01-04 | -2.763631 | -1.473717 | -3.099774 | 2.0 | 0.0 | 
| 2013-01-05 | -5.703749 | -6.966019 | -4.157890 | 0.0 | -1.0 | 
| 2013-01-06 | NaN | NaN | NaN | NaN | NaN | 
对数据运用函数
df.apply(np.cumsum)
| A | B | C | D | F | |
|---|---|---|---|---|---|
| 2013-01-01 | 0.000000 | 0.000000 | 0.357454 | 5 | NaN | 
| 2013-01-02 | -0.349901 | -0.848231 | -0.147063 | 10 | 1.0 | 
| 2013-01-03 | -0.051650 | 0.441509 | -1.416758 | 15 | 3.0 | 
| 2013-01-04 | 0.184719 | 1.967791 | -1.516532 | 20 | 6.0 | 
| 2013-01-05 | -0.519030 | 0.001772 | -0.674423 | 25 | 10.0 | 
| 2013-01-06 | 0.541987 | 0.442587 | -1.790320 | 30 | 15.0 | 
df.apply(lambda x:x.max()-x.min())
A    1.764767
B    3.492301
C    2.111804
D    0.000000
F    4.000000
dtype: float64
柱状图
s=pd.Series(np.random.randint(0,7,size=10))
s
0    2
1    6
2    3
3    1
4    6
5    4
6    4
7    6
8    6
9    6
dtype: int64
字符串的方法
Series在str属性中配备了一组字符串处理方法,可以方便的对数组的每个元素进行操作,并且模式匹配通常使用正则表达式
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
合并
连接
pandas提供了各种工具,可以方便的将Series、DataFrame和Panel对象组合在一起,并在连接、合并类型操作的情况下,为索引和关系代数功能提供各种集合逻辑
df=pd.DataFrame(np.random.randn(10,4))
df
| 0 | 1 | 2 | 3 | |
|---|---|---|---|---|
| 0 | -2.115351 | -0.715676 | 0.307033 | 1.042703 | 
| 1 | 0.957212 | -0.310875 | 0.978699 | 0.597034 | 
| 2 | 0.034715 | 1.315929 | -2.278538 | -1.652614 | 
| 3 | -0.729501 | 0.650241 | 0.783674 | -2.251146 | 
| 4 | 0.440467 | 0.510737 | -0.208779 | -0.693988 | 
| 5 | -0.017431 | -0.677659 | 0.792783 | 1.583612 | 
| 6 | -1.180695 | 0.824008 | -0.687270 | 0.705201 | 
| 7 | 1.579882 | -0.300540 | 0.210331 | 0.757258 | 
| 8 | -1.758054 | 0.096074 | -1.010636 | -0.731821 | 
| 9 | -0.475845 | -0.628462 | 0.160693 | 0.055768 | 
pieces=[df[:3],df[3:7],df[7:]]
pd.concat(pieces)
| 0 | 1 | 2 | 3 | |
|---|---|---|---|---|
| 0 | -2.115351 | -0.715676 | 0.307033 | 1.042703 | 
| 1 | 0.957212 | -0.310875 | 0.978699 | 0.597034 | 
| 2 | 0.034715 | 1.315929 | -2.278538 | -1.652614 | 
| 3 | -0.729501 | 0.650241 | 0.783674 | -2.251146 | 
| 4 | 0.440467 | 0.510737 | -0.208779 | -0.693988 | 
| 5 | -0.017431 | -0.677659 | 0.792783 | 1.583612 | 
| 6 | -1.180695 | 0.824008 | -0.687270 | 0.705201 | 
| 7 | 1.579882 | -0.300540 | 0.210331 | 0.757258 | 
| 8 | -1.758054 | 0.096074 | -1.010636 | -0.731821 | 
| 9 | -0.475845 | -0.628462 | 0.160693 | 0.055768 | 
加入(Join)
left=pd.DataFrame({'key':['foo','foo'],'lval':[1,2]})
left
| key | lval | |
|---|---|---|
| 0 | foo | 1 | 
| 1 | foo | 2 | 
right=pd.DataFrame({'key':['foo','foo'],'rval':[4,5]})
right
| key | rval | |
|---|---|---|
| 0 | foo | 4 | 
| 1 | foo | 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 | 
left=pd.DataFrame({'key':['foo','bar'],'lval':[1,2]})
left
| key | lval | |
|---|---|---|
| 0 | foo | 1 | 
| 1 | bar | 2 | 
right=pd.DataFrame({'key':['foo','bar'],'rval':[4,5]})
right
| key | rval | |
|---|---|---|
| 0 | foo | 4 | 
| 1 | bar | 5 | 
pd.merge(left,right,on='key')
| key | lval | rval | |
|---|---|---|---|
| 0 | foo | 1 | 4 | 
| 1 | bar | 2 | 5 | 
添加(append)
添加行到DataFrame
df=pd.DataFrame(np.random.randn(8,4),columns=['A','B','C','D'])
df
| A | B | C | D | |
|---|---|---|---|---|
| 0 | -0.630559 | -0.355815 | 1.455790 | 0.951718 | 
| 1 | -0.336212 | 0.378611 | 0.748053 | -0.637500 | 
| 2 | 1.470661 | 2.488843 | 0.866483 | 0.166350 | 
| 3 | 0.893054 | 0.195543 | 1.801191 | 0.216009 | 
| 4 | -2.288886 | 1.708138 | 1.195167 | 0.104008 | 
| 5 | 1.174860 | 0.027715 | 0.451720 | -1.244097 | 
| 6 | -0.883463 | 0.576165 | -0.303804 | -1.090623 | 
| 7 | 0.731934 | 0.624394 | -1.269733 | 0.246732 | 
s=df.iloc[3]
df.append(s,ignore_index=True)
| A | B | C | D | |
|---|---|---|---|---|
| 0 | -0.630559 | -0.355815 | 1.455790 | 0.951718 | 
| 1 | -0.336212 | 0.378611 | 0.748053 | -0.637500 | 
| 2 | 1.470661 | 2.488843 | 0.866483 | 0.166350 | 
| 3 | 0.893054 | 0.195543 | 1.801191 | 0.216009 | 
| 4 | -2.288886 | 1.708138 | 1.195167 | 0.104008 | 
| 5 | 1.174860 | 0.027715 | 0.451720 | -1.244097 | 
| 6 | -0.883463 | 0.576165 | -0.303804 | -1.090623 | 
| 7 | 0.731934 | 0.624394 | -1.269733 | 0.246732 | 
| 8 | 0.893054 | 0.195543 | 1.801191 | 0.216009 | 
分组(Group)
这里的是指涉及到下列一项或多项步骤的程序:
- 根据一些标准将数据分成组
- 将一个函数独立的应用于每个组
- 将结果组合成数据结构
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)})
df
| A | B | C | D | |
|---|---|---|---|---|
| 0 | foo | one | 1.646966 | 1.182807 | 
| 1 | bar | one | -0.455323 | -0.005714 | 
| 2 | foo | two | 0.053325 | 0.126067 | 
| 3 | bar | three | -0.686848 | -0.934492 | 
| 4 | foo | two | -0.716243 | 0.917926 | 
| 5 | bar | two | -2.104489 | -0.778538 | 
| 6 | foo | one | -0.535159 | -1.221881 | 
| 7 | foo | three | 0.232483 | -0.466755 | 
df.groupby('A').sum()
| C | D | |
|---|---|---|
| A | ||
| bar | -3.246660 | -1.718744 | 
| foo | 0.681373 | 0.538164 | 
df.groupby(['A','B']).sum()
| C | D | ||
|---|---|---|---|
| A | B | ||
| bar | one | -0.455323 | -0.005714 | 
| three | -0.686848 | -0.934492 | |
| two | -2.104489 | -0.778538 | |
| foo | one | 1.111807 | -0.039074 | 
| three | 0.232483 | -0.466755 | |
| two | -0.662917 | 1.043993 | 
更改形状(Reshaping)
堆栈
tuples=list(zip(*[['bar', 'bar', 'baz', 'baz',
                    'foo', 'foo', 'qux', 'qux'],
                   ['one', 'two', 'one', 'two',
                    'one', 'two', 'one', 'two']]))
tuples
[('bar', 'one'),
 ('bar', 'two'),
 ('baz', 'one'),
 ('baz', 'two'),
 ('foo', 'one'),
 ('foo', 'two'),
 ('qux', 'one'),
 ('qux', 'two')]
index=pd.MultiIndex.from_tuples(tuples,names=['first','second'])
index
MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], ['one', 'two']],
           labels=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]],
           names=['first', 'second'])
df=pd.DataFrame(np.random.randn(8,2),index=index,columns=['A','B'])
df2 = df[:4]
df2
| A | B | ||
|---|---|---|---|
| first | second | ||
| bar | one | -0.282920 | -0.784727 | 
| two | 0.394472 | -0.990833 | |
| baz | one | 0.415449 | 0.788460 | 
| two | -0.714289 | 0.114039 | 
stack方法压缩数据dataframe列中的一个级别
stacked=df2.stack()
stacked
first  second   
bar    one     A   -0.282920
               B   -0.784727
       two     A    0.394472
               B   -0.990833
baz    one     A    0.415449
               B    0.788460
       two     A   -0.714289
               B    0.114039
dtype: float64
stack的逆操作是unstack,它在缺省情况下解析栈的最有一层(level)
stacked.unstack()
| A | B | ||
|---|---|---|---|
| first | second | ||
| bar | one | -0.282920 | -0.784727 | 
| two | 0.394472 | -0.990833 | |
| baz | one | 0.415449 | 0.788460 | 
| two | -0.714289 | 0.114039 | 
stacked.unstack(1)
| second | one | two | |
|---|---|---|---|
| first | |||
| bar | A | -0.282920 | 0.394472 | 
| B | -0.784727 | -0.990833 | |
| baz | A | 0.415449 | -0.714289 | 
| B | 0.788460 | 0.114039 | 
stacked.unstack(0)
| first | bar | baz | |
|---|---|---|---|
| second | |||
| one | A | -0.282920 | 0.415449 | 
| B | -0.784727 | 0.788460 | |
| two | A | 0.394472 | -0.714289 | 
| B | -0.990833 | 0.114039 | 
数据透视表
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)})
df
| A | B | C | D | E | |
|---|---|---|---|---|---|
| 0 | one | A | foo | -1.185747 | -1.072726 | 
| 1 | one | B | foo | -0.160385 | -0.756112 | 
| 2 | two | C | foo | -0.666467 | -0.009739 | 
| 3 | three | A | bar | -1.737305 | 0.300929 | 
| 4 | one | B | bar | 2.434363 | 2.395882 | 
| 5 | one | C | bar | -0.601540 | 0.687986 | 
| 6 | two | A | foo | 1.680735 | 0.885203 | 
| 7 | three | B | foo | -2.650518 | -0.393771 | 
| 8 | one | C | foo | -0.900106 | 1.274196 | 
| 9 | one | A | bar | -0.201902 | 0.703524 | 
| 10 | two | B | bar | 0.693622 | 0.832540 | 
| 11 | three | C | bar | -0.700483 | 0.018224 | 
可以很轻松的从这个数据创建数据透视表
pd.pivot_table(df,values='D',index=['A','B'],columns=['C'])
| C | bar | foo | |
|---|---|---|---|
| A | B | ||
| one | A | -0.201902 | -1.185747 | 
| B | 2.434363 | -0.160385 | |
| C | -0.601540 | -0.900106 | |
| three | A | -1.737305 | NaN | 
| B | NaN | -2.650518 | |
| C | -0.700483 | NaN | |
| two | A | NaN | 1.680735 | 
| B | 0.693622 | NaN | |
| C | NaN | -0.666467 | 
时间序列
pandas具有在频率转换期间执行重采样操作的简单、强大和高效的功能,例如将第二个数据转换为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').sum()
2012-01-01    23221
Freq: 5T, dtype: int64
时区表示
rng=pd.date_range('3/6/2012 00:00',periods=5,freq='D')
ts=pd.Series(np.random.randn(len(rng)),rng)
ts
2012-03-06   -0.249071
2012-03-07   -0.995306
2012-03-08    0.556063
2012-03-09   -1.112809
2012-03-10   -0.440461
Freq: D, dtype: float64
ts_utc=ts.tz_localize('UTC')
ts_utc
2012-03-06 00:00:00+00:00   -0.249071
2012-03-07 00:00:00+00:00   -0.995306
2012-03-08 00:00:00+00:00    0.556063
2012-03-09 00:00:00+00:00   -1.112809
2012-03-10 00:00:00+00:00   -0.440461
Freq: D, dtype: float64
转换成另一个时区
ts_utc.tz_convert('US/Eastern')
2012-03-05 19:00:00-05:00   -0.249071
2012-03-06 19:00:00-05:00   -0.995306
2012-03-07 19:00:00-05:00    0.556063
2012-03-08 19:00:00-05:00   -1.112809
2012-03-09 19:00:00-05:00   -0.440461
Freq: D, dtype: float64
转换之间的时间跨度表示
rng=pd.date_range('1/1/2012',periods=5,freq='M')
ts=pd.Series(np.random.randn(len(rng)),index=rng)
ts
2012-01-31    0.298762
2012-02-29    0.956746
2012-03-31    0.450267
2012-04-30   -0.379958
2012-05-31    0.465818
Freq: M, dtype: float64
ps=ts.to_period()
ps
2012-01    0.298762
2012-02    0.956746
2012-03    0.450267
2012-04   -0.379958
2012-05    0.465818
Freq: M, dtype: float64
ps.to_timestamp()
2012-01-01    0.298762
2012-02-01    0.956746
2012-03-01    0.450267
2012-04-01   -0.379958
2012-05-01    0.465818
Freq: MS, dtype: float64
周期(period)和时间戳之间的转换可以使用一些方便的算术函数
在下面的例子中,将一个以11月为结束年份的季度频率转换为季度结束后一个月末的上午9点:
prng=pd.period_range('1990Q1','2000Q4',freq='Q-NOV')
ts=pd.Series(np.random.randn(len(prng)),prng)
ts.index=(prng.asfreq('M','e')++1).asfreq('H','s')++9
ts.head()
1990-03-01 09:00   -0.651261
1990-06-01 09:00    0.327260
1990-09-01 09:00    1.186971
1990-12-01 09:00    2.703336
1991-03-01 09:00   -0.829313
Freq: H, dtype: float64
分类
df=pd.DataFrame({"id": [1, 2, 3, 4, 5, 6],
                 "raw_grade": ['a', 'b', 'b', 'a', 'a', 'e']})
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'].cat.categories=["very good","good","very bad"]
df['grade']=df['grade'].cat.set_categories(["very bad", "bad", "medium","good", "very good"])
df['grade']
0    very good
1         good
2         good
3    very good
4    very good
5     very bad
Name: grade, dtype: category
Categories (5, object): [very bad, bad, medium, good, very good]
排序是按照类别中的顺序进行的,不是按照词法顺序进行的
df.sort_values(by='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 | 
按照类别列分组,也会显示空类别
df.groupby('grade').size()
grade
very bad     1
bad          0
medium       0
good         2
very good    3
dtype: int64
画图
import matplotlib.pyplot as plt
ts=pd.Series(np.random.randn(1000),
              index=pd.date_range('1/1/2000', periods=1000))
ts=ts.cumsum()
ts.plot()

在DataFrame上,plot方法可以方便绘制所有带有便签的列
df=pd.DataFrame(np.random.randn(1000,4),index=ts.index,columns=['A','B','C','D'])
df=df.cumsum()
plt.figure()
df.plot()
plt.legend(loc='best')

获取数据
csv
写入csv文件
df.to_csv('foo.csv')
读csv文件
pd.read_csv('foo.csv')
HDF5
写入hdf5存储
df.to_hdf('foo.h5','df')
读取
pd.read_hdf('foo.h5','df')
excel
写入excel
df.to_excel('foo.xlsx',sheet_name='sheet1')
读取
pd.read_excel('foo.xlsx','sheet1',index_col=None,na_values=['NA'])
陷阱
如果你执行一个操作,可能会看到一个异常
if pd.Series([False, True, False]):
    print('True')
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
