Python数据处理:IPython使用学习笔记
Python数据处理:Numpy 学习笔记
Python数据处理:Pandas 学习笔记
一. pandas
1. 介绍
pandas是建立在Numpy基础上的高效数据分析处理库
主要包括:
- Series 一维带标签的同种类型的数组
- DataFrame 二维代表前的大小可变的各种数据类型可以不同的二维表格
- Panel 三维带标签的大小可变的数据
数据呈直线排列,并且数据和数据标签在默认情况下是相互对齐的
2. pandas引用
import pandas as pd
from pandas import Series, DataFrame
import numpy as np
二. Series
1. 创建Series序列
s = pd.Series(np.random.rand(5)) # 通过np创建Series
''' 左侧的是索引值
0 0.048789
1 0.068063
2 0.103401
3 0.136115
4 0.166982
dtype: float64
'''
### 可以用list作为索引,创建序列
index_2 = ['a','b','c','d','e']
s2 = pd.Series(np.random.randint(1,6,(5,)),index=index_2)
'''
a 3
b 2
c 5
d 2
e 5
dtype: int32
'''
### 用字典格式,则key为序列
dict_a = {'m':2, 'n':1, 'o':5, 'p':2}
s3 = Series(dict_a)
'''
m 2
n 1
o 5
p 2
dtype: int64
'''
s4 = Series(dict_a, ['o','m','q','p']) # 也可再指定序列,其中值从dict[key]中取,取不到则为NaN
'''
o 5.0
m 2.0
q NaN
p 2.0
dtype: float64
'''
2. Series属性
s.index # 得到索引,RangeIndex(start=0, stop=5, step=1)
s.values # 得到值,array([ 0.0487887 , 0.0680634 , 0.10340053, 0.13611469, 0.16698198])
3. 序列取值与赋值
### 序列取值
s4['m'] # 2.0
s4[['m','o']]
'''
m 2.0
o 5.0
dtype: float64
'''
s4['q'] = 1 # 赋值
'q' in s4 # 判断'q'是否在s4的索引中 True
'a' in s4 # False
s4.get('q')
4. 序列分片
### 序列分片
s[1:3]
'''
1 0.068063
2 0.103401
dtype: float64
'''
5. 序列判断与计算
s4[s4>3] # 有些像np的布尔索引
s4[s4==2] = 4 # 修改其中2的值,为4
s4 * 2 # 乘法,作用于每个数上,与np乘法相同
'''
o 10.0
m 4.0
q 2.0
p 4.0
dtype: float64
'''
np.sin(s4) # np的方法也能用在Series上
'''
o -0.958924
m 0.909297
q 0.841471
p 0.909297
dtype: float64
'''
- 序列和数组的一个重要的不同点: 不同序列之间进行运算时,相同索引位置会自动对齐,并进行运算
### 特殊点
s4[1::] + s4[::-1]
'''
s4[1::] + s4[::-1] == ?
m 2.0 p 2.0 m 4.0
q 1.0 q 1.0 o NaN
p 2.0 m 2.0 p 4.0
o 5.0 q 2.0
可以看到,两个Series相加,并没有按顺序,而是自动合并了相同的索引位置的值,做加法
这很重要,这一特性是pandas区别于大多数数据处理工具的重要特性
'''
三. DataFrame
1. 创建DF
### 初始化:用字典dict()
data = {'姓名':['李白','辛弃疾','杜甫','苏轼','孟浩然','韩愈'],
'年龄':[11,12,13,14,15,16],
'语文':[97,90,92,94,88,86],
'数学':[71,91,84,66,72,74],
'物理':[53,82,70,73,81,70],
'生物':[78,62,83,72,55,50]
}
df = DataFrame(data)
''' 字典的键成为column列标签,行标签自动生成从0开始的自增序列
姓名 年龄 数学 物理 生物 语文
0 李白 34 71 53 78 97
1 辛弃疾 11 91 82 62 90
2 杜甫 73 84 70 83 92
3 苏轼 41 66 73 72 94
4 孟浩然 99 72 81 55 88
5 韩愈 82 74 70 50 86
'''
# 通过columns和index指定标签、列名和顺序
df2 = DataFrame(data, columns=['姓名','数学','语文','物理','生物','年龄'],
index=['a','b','c','d','e','f'])
'''
姓名 数学 语文 物理 生物 年龄
a 李白 71 97 53 78 34
b 辛弃疾 91 90 82 62 11
c 杜甫 84 92 70 83 73
d 苏轼 66 94 73 72 41
e 孟浩然 72 88 81 55 99
f 韩愈 74 86 70 50 82
'''
### 初始化:用Series
data3 = {'姓名':Series(['李白','辛弃疾','杜甫','苏轼','孟浩然','韩愈'],
index = ['a','b','c','d','e','f']),
'年龄':Series([11,12,13,14,15,16], index = ['a','f','b','c','d','e']),
'诗词':Series([0,0,1,1,1,1], index = ['f','e','a','b','c','d'])
}
df3 = DataFrame(data3) # 注意这里合并时,并不是用顺序,而是用index自动合并
'''
姓名 年龄 诗词
a 李白 11 1
b 辛弃疾 13 1
c 杜甫 14 1
d 苏轼 15 1
e 孟浩然 16 0
f 韩愈 12 0
'''
2. 属性
### 属性
df2.index # index索引对象,索引对象不允许修改 df2.index = [1,2,3,4,5,6]会报错
df2.columns # columns
df2.values # 数据 类型type=np.ndarray
df2.head(5) # 前5行数据
df2.tail(3) # 后3行数据
df2.reindex(['f','e','aa']) # 用reindex来返回新df,从原数据找出对应索引的值,不存在则用NaN。可以通过fill_value、method等参数设置默认值或取值方法
'''
姓名 数学 语文 物理 生物 年龄
f 韩愈 74.0 86.0 70.0 50.0 82.0
e 孟浩然 72.0 88.0 81.0 55.0 99.0
aa NaN NaN NaN NaN NaN NaN
'''
3. 切片或取值
a. 列操作
## a. 取指定column列
# 方法一:传统取法,可以传入某column名称,来取对应的列
df2['姓名']
''' type是Series
a 李白
b 辛弃疾
c 杜甫
d 苏轼
e 孟浩然
f 韩愈
Name: 姓名, dtype: object
'''
## 方法二:像调用属性和方法一样,直接使用 .column取
df2.年龄
'''
a 34
b 11
c 73
d 41
e 99
f 82
Name: 年龄, dtype: int64
'''
## b. 列切片 可以传入多个column名称,来取对应的列,或者重新排序
df2[['姓名','年龄']]
''' type是DataFrame
姓名 年龄
a 李白 34
b 辛弃疾 11
c 杜甫 73
d 苏轼 41
e 孟浩然 99
f 韩愈 82
'''
b. 行操作
## a.取特定行
df2.loc['a']
''' type是Series
姓名 李白
数学 71
语文 97
物理 53
生物 78
年龄 34
Name: a, dtype: object
'''
# 要注意不能用df[特定行index],这个规定决定了下面两种取值方式都会报错
# df2[['a']] df2['a']
## b.多行切片
# 方法一:loc[行范围] 此时行范围不能是list或者特定值
df2.loc[['a','b']]
''' type是DataFrame
姓名 数学 语文 物理 生物 年龄
a 李白 71 97 53 78 34
b 辛弃疾 91 90 82 62 11
'''
## 方法二:数组方式切片
df2[1:3] # 可以用数字范围,说明index是有顺序的
'''
姓名 数学 语文 物理 生物 年龄
b 辛弃疾 91 90 82 62 11
c 杜甫 84 92 70 83 73
'''
df2['a':'d'] # 也可以用index本身的名称
''' 包含d行,居然没有去除
姓名 数学 语文 物理 生物 年龄
a 李白 71 97 53 78 34
b 辛弃疾 91 90 82 62 11
c 杜甫 84 92 70 83 73
d 苏轼 66 94 73 72 41
'''
# 但不能用list,如:df2[['a','d']] 会报错
c. 行列同时切片
## a.方法一:df.loc[行index范围, 列column范围]
df2.loc[['a','b'],['年龄','姓名']] # index 可以是list
'''
年龄 姓名
a 34 李白
b 11 辛弃疾
'''
df2.loc['a':'c',['年龄','姓名']] # index 可以是范围
'''
年龄 姓名
a 34 李白
b 11 辛弃疾
c 73 杜甫
'''
df2.loc['a',['年龄','姓名']] # index 可以是特定值
'''
年龄 姓名
a 34 李白
c 73 杜甫
'''
## b. 方法二:df[列column范围][行index范围] 或者:df[行index范围][列column范围](此时index不能为特定行)
df2[['姓名','年龄','生物']]['a':'d']
'''
姓名 年龄 生物
a 李白 34 78
b 辛弃疾 11 62
c 杜甫 73 83
d 苏轼 41 72
'''
df2['姓名']['a':'d'] # column 为单一值
'''
a 李白
b 辛弃疾
c 杜甫
d 苏轼
Name: 姓名, dtype: object
'''
# 也可以颠倒,但index放前面时,不允许index为list或者特定项
df2['a':'d'][['姓名','年龄','生物']]
'''
姓名 年龄 生物
a 李白 34 78
b 辛弃疾 11 62
c 杜甫 73 83
d 苏轼 41 72
'''
df2['a':'d']['姓名']
'''
a 李白
b 辛弃疾
c 杜甫
d 苏轼
Name: 姓名, dtype: object
'''
# 下面两种都会报错
#df2[['a','b']][['姓名','年龄','生物']]
#df2['a'][['姓名','年龄','生物']]
## 同时,直接取法也不允许像loc那么写:df2['a':'d','姓名']
d. 取特定坐标的值
## a.loc[index坐标,column坐标]
df2.loc['a','年龄'] # 取特定的值 本例:34 type=int
## b.df[column坐标][index坐标] 与loc相反,因为[index坐标]如果放前,不能为特定值
df2['年龄']['a']
e. 通过位置进行切片
df.iloc[1:3,0:3] # 用位置切片
'''
姓名 年龄 数学
1 辛弃疾 11 91
2 杜甫 73 84
'''
df.iloc[:,::2] # 隔列切片
'''
姓名 数学 生物
0 李白 71 78
1 辛弃疾 91 62
2 杜甫 84 83
3 苏轼 66 72
4 孟浩然 72 55
5 韩愈 74 50
'''
df.iloc[1,0] # 取值,'辛弃疾'
'这里需要留意:
- 对loc/iloc函数来说,始终都是loc(行,列),无论取值或者切片,都是最稳妥的方式(非常推荐)
- 但对坐标法df[]取值:
a. df[列]为主要取列方式(取列时推荐) b. 坐标法想要作用在行上,唯有当df[index_start:index_end]这种表示法,才正常;传单个行或者list都会错(不推荐坐标法取行,容易写错) c. 这种方法取特定值,则只能用df[列][行] (不太推荐,容易写反,能记住也可以用)
4. 增加、删除列(都是对原数据进行了修改)
# 方法一:指定某一数
df2['化学'] = 60 # 指定某一数
''' 增加了一列:化学
姓名 数学 语文 物理 生物 年龄 化学
a 李白 71 97 53 78 34 60
b 辛弃疾 91 90 82 62 11 60
c 杜甫 84 92 70 83 73 60
d 苏轼 66 94 73 72 41 60
e 孟浩然 72 88 81 55 99 60
f 韩愈 74 86 70 50 82 60
'''
# 方法二:指定一个list
df2['化学'] = [70,60,50,40,30,20] # 也可以直接用list
# 方法三:用insert方法
df2.insert(4, '化学',np.array([70,60,50,40,30,20])) # 用insert指定插入位置
'''
姓名 数学 语文 物理 化学 生物 年龄
a 李白 71 97 53 70 78 34
b 辛弃疾 91 90 82 60 62 11
c 杜甫 84 92 70 50 83 73
d 苏轼 66 94 73 40 72 41
e 孟浩然 72 88 81 30 55 99
f 韩愈 74 86 70 20 50 82
'''
删除
## 删除
# 方法一:del
del df2['化学']
'''
姓名 数学 语文 物理 生物 年龄
a 李白 71 97 53 78 34
b 辛弃疾 91 90 82 62 11
c 杜甫 84 92 70 83 73
d 苏轼 66 94 73 72 41
e 孟浩然 72 88 81 55 99
f 韩愈 74 86 70 50 82
'''
# 方法二: pop()
chemic = df2.pop('化学')
# 方法三:drop
df2.drop('生物',axis=1)
5. 增加删除行
### 增加行
df2.loc['g'] = ['白居易', 83, 58, 91, 71, 70]
'''
姓名 数学 语文 物理 生物 年龄
a 李白 71 97 53 78 34
b 辛弃疾 91 90 82 62 11
c 杜甫 84 92 70 83 73
d 苏轼 66 94 73 72 41
e 孟浩然 72 88 81 55 99
f 韩愈 74 86 70 50 82
g 白居易 83 58 91 71 70
'''
# 删除行
df2.drop('g',inplace=True)
5. 运算对齐特性
### 结果为:相同行列索引的值进行运算的结果交集
data_a = DataFrame(np.arange(12).reshape(3,4),columns=['a','b','c','d'], index= range(1,4))
'''
a b c d
1 0 1 2 3
2 4 5 6 7
3 8 9 10 11
'''
data_b = DataFrame(np.random.randint(0,6,(3,4)),columns=['a','b','c','e'], index= range(2,5))
'''
a b c e
2 4 2 2 0
3 5 5 0 1
4 5 4 4 1
'''
计算时,pandas会自动对齐,相同坐标的数进行计算
r = data_a + data_b
''' 相同位置的数,相加,否则为NaN
a b c d e
1 NaN NaN NaN NaN NaN
2 8.0 7.0 8.0 NaN NaN
3 13.0 14.0 10.0 NaN NaN
4 NaN NaN NaN NaN NaN
'''
扩充转换机制
### pandas有与numpy相同的扩充转换机制
data_b - data_b.loc[2]
''' 可以看到不只是第一行,下面每一行都减了第一行的数据,说明进行了扩充转换
a b c e
2 0 0 0 0
3 1 3 -2 1
4 1 2 2 1
'''
6. pandas空值问题
### 预备知识
None == None # 为True
np.nan == np.nan # 为False
np.nan is np.nan # 为True
"""pandas空值问题"""
### 在pandas中,None和np.nan都是空值
test = DataFrame(np.array([[None,np.nan,1],[2,None,np.nan]]),columns=list('abc'),index=range(2))
'''
a b c
0 None NaN 1
1 2 None NaN
'''
test.loc[0] == np.nan # 这样判断出来的结果都为False
'''
a False
b False
c False
'''
fillna() 填充空值
### fillna()可以实现空值填充功能
test.fillna(3)
''' 所有NaN和None都被填充了3
a b c
0 3 3 1
1 2 3 3
'''
### fillna() 更高级用法
r.loc[5] = r.loc[1] # 增加一行,值同第一行
r.loc[6] = [np.random.randint(0,6) for i in range(5)]
''' 创造备用数据
a b c d e
1 NaN NaN NaN NaN NaN
2 8.0 7.0 8.0 NaN NaN
3 13.0 14.0 10.0 NaN NaN
4 NaN NaN NaN NaN NaN
5 NaN NaN NaN NaN NaN
6 4.0 1.0 2.0 3.0 1.0
'''
r.fillna(method='pad',limit=1) # pad 用Nan上一行的数据,来填充这个NaN的内容
'''
a b c d e
1 NaN NaN NaN NaN NaN
2 8.0 7.0 8.0 NaN NaN
3 13.0 14.0 10.0 NaN NaN
4 13.0 14.0 10.0 NaN NaN
5 NaN NaN NaN NaN NaN
6 4.0 1.0 2.0 3.0 1.0
'''
r.dropna() # 丢弃有空值的行或
'''
a b c d e
6 4.0 1.0 2.0 3.0 1.0
'''
7. 多级索引
a. 创建多级索引
'''多级索引'''
arrays = [['一班','一班','一班','二班','二班'],['李白','杜甫','白居易','苏轼','李白']]
tuples = list(zip(*arrays))
index = pd.Index(tuples, name=["班级","老师"]) # 创建了多级索引index
'''
MultiIndex(levels=[['一班', '二班'], ['李白', '杜甫', '白居易', '苏轼']],
labels=[[0, 0, 0, 1, 1], [0, 1, 2, 3, 0]],
names=['班级', '老师'])
'''
# 创建多维索引数组,每个老师每年每班合格学生数
multi_data = DataFrame(np.random.randint(30,50,(5,3)),columns=[2016,2017,2018],index = index)
''' 这里是多级索引的DataFrame,注意column是分行的
2016 2017 2018
班级 老师
一班 李白 40 46 48
杜甫 32 35 46
白居易 48 45 47
二班 苏轼 33 37 33
李白 31 31 43
'''
multi_data.T # 可以转置,这样columns是多维索引
'''
班级 一班 二班
老师 李白 杜甫 白居易 苏轼 李白
2016 40 32 48 33 31
2017 46 35 45 37 31
2018 48 46 47 33 43
'''
# 也可以直接创建列的多维索引
t_multi_data = DataFrame(multi_data.values.transpose(),index=[2016,2017,2018],columns = index)
b.多维索引取数
### 多维索引取数
multi_data[2016]['一班','李白'] # 40
multi_data.loc[('一班','李白'),2016] # 40
multi_data.iloc[0,0] # 40
t_multi_data['一班','李白'][2016] # 40
t_multi_data.loc[2016,('一班','李白')] # 40
t_multi_data.iloc[0,0] # 40
c. 多级索引数组切片
# 多级索引数组切片
multi_data.loc['一班'] # 能单独取某个维度的index
'''
2016 2017 2018
老师
李白 40 46 48
杜甫 32 35 46
白居易 48 45 47
'''
# multi_data.loc['李白'] 只取李白不能生效,可以用swaplevel()切换索引后,再进行筛选
multi_data.loc['一班', '杜甫'] # 与 multi_data.loc[('一班', '杜甫')]相同
'''
2016 32
2017 35
2018 46
Name: (一班, 杜甫), dtype: int32
'''
d.多级索引数组变换
### 交换索引
multi_data.swaplevel()
'''
2016 2017 2018
老师 班级
李白 一班 40 46 48
杜甫 一班 32 35 46
白居易 一班 48 45 47
苏轼 二班 33 37 33
李白 二班 31 31 43
'''
### 舍弃index,转成普通DataFrame(groupby后就为MultiIndex格式数据,需要通过此步骤再转成df)
ordinary_data = multi_data.reset_index() # 注意不是reindex()
'''
班级 老师 2016 2017 2018
0 一班 李白 40 46 48
1 一班 杜甫 32 35 46
2 一班 白居易 48 45 47
3 二班 苏轼 33 37 33
4 二班 李白 31 31 43
'''
8. 组合数据
a. concat()
"""组合数据"""
### pd.concat
df1 = DataFrame(np.arange(12).reshape(3,4),columns=tuple('ABCD'))
'''
A B C D
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
'''
df2 = DataFrame(np.random.choice(list("abcdefg"),12).reshape(3,4),columns=tuple('CDEF'),index=[i for i in range(2,5)])
'''
C D E F
2 g g e b
3 a e d d
4 e f d c
'''
pd.concat([df1,df2]) # 相同column列会组合,无值则用NaN代替,但列上并不会合并,例如本例有两行index都为2
'''
A B C D E F
0 0.0 1.0 2 3 NaN NaN
1 4.0 5.0 6 7 NaN NaN
2 8.0 9.0 10 11 NaN NaN
2 NaN NaN g g e b
3 NaN NaN a e d d
4 NaN NaN e f d c
'''
pd.concat([df1,df2], axis=1) # 横向组合,相同index行会组合,无值用NaN代替
'''
A B C D C D E F
0 0.0 1.0 2.0 3.0 NaN NaN NaN NaN
1 4.0 5.0 6.0 7.0 NaN NaN NaN NaN
2 8.0 9.0 10.0 11.0 g g e b
3 NaN NaN NaN NaN a e d d
4 NaN NaN NaN NaN e f d c
'''
pd.concat([df1,df2], axis=1,join='inner') # join为inner,只显示共有的index=2 的行
'''
A B C D C D E F
2 8 9 10 11 g g e b
'''
pd.concat([df1,df2], join='inner') # 列上共有的CD两列
'''
C D
0 2 3
1 6 7
2 10 11
2 g g
3 a e
4 e f
'''
b. append
### append 附加,与concat在列上axis=0上叠加相似
df1.append(df2)
c. merge()
### merge() 与数据库非常相似
df1 = pd.DataFrame(np.arange(12).reshape(3,4),columns=list("ABCD"))
'''
A B C D
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
'''
df2 = pd.DataFrame({'D':[3,11,6],'E':['a','e','b'],'C':[7,10,2]})
'''
C D E
0 7 3 a
1 10 11 e
2 2 6 b
'''
pd.merge(df1,df2,on='D') # 根据'D'列的数据进行合并
'''因为C在df1、df2中都有,所以会被改后缀
A B C_x D C_y E
0 0 1 2 3 7 a
1 8 9 10 11 10 e
'''
pd.merge(df1,df2,on='D',how='left') # 左连接,右边匹配不到的补零
'''
A B C_x D C_y E
0 0 1 2 3 7.0 a
1 4 5 6 7 NaN NaN
2 8 9 10 11 10.0 e
'''
pd.merge(df1,df2,on=['D','C'],how='outer') # 以两列作为共选字段,进行匹配
'''
A B C D E
0 0.0 1.0 2 3 NaN
1 4.0 5.0 6 7 NaN
2 8.0 9.0 10 11 e
3 NaN NaN 7 3 a
4 NaN NaN 2 6 b
'''
d. combine_first()
### combine_first() 合并
df1.loc[0].combine_first(df2.loc[0])
'''
A 0
B 1
C 2
D 3
E a # E在df1中不存在,则取df2的值
Name: 0, dtype: object
'''
9. groupby()分组
"""分组 groupby"""
df = multi_data.reset_index() # 用之前df的一个例子
'''
班级 老师 2016 2017 2018
0 一班 李白 40 46 48
1 一班 杜甫 32 35 46
2 一班 白居易 48 45 47
3 二班 苏轼 33 37 33
4 二班 李白 31 31 43
'''
### groupby分类,此时grouped是一个对象
grouped = df.groupby('班级')
## 进一步对groupby后的数据进行运算
grouped.sum() # 求和
''' 返回的是一个MultiIndex的对象
2016 2017 2018
班级
一班 120 126 141
二班 64 68 76
'''
grouped.mean() # 求平均
'''
2016 2017 2018
班级
一班 40 42 47
二班 32 34 38
'''
### 多个条件groupby,本质上没有先后顺序
df.groupby(['老师','班级']).sum()
'''
2016 2017 2018
老师 班级
李白 一班 40 46 48
二班 31 31 43
杜甫 一班 32 35 46
白居易 一班 48 45 47
苏轼 二班 33 37 33
'''
### groupby对象是个迭代器,可以循环查看
for (a,b), group in df.groupby(['老师','班级']):
print(a,b)
print(group)
'''
李白 一班
班级 老师 2016 2017 2018
0 一班 李白 40 46 48
李白 二班
班级 老师 2016 2017 2018
4 二班 李白 31 31 43
杜甫 一班
班级 老师 2016 2017 2018
1 一班 杜甫 32 35 46
白居易 一班
班级 老师 2016 2017 2018
2 一班 白居易 48 45 47
苏轼 二班
班级 老师 2016 2017 2018
3 二班 苏轼 33 37 33
'''
### 可以选定df若干列进行分组
# 方法一:
df[[2016,2017]].groupby(df['班级']).sum() # 以'班级'为组,对[2016,2017]进行分组
'''
2016 2017
班级
一班 120 126
二班 64 68
'''
# 方法二:
df[['班级',2016,2017]].groupby('班级').sum() # 与上面的结果相同
'''
2016 2017
班级
一班 120 126
二班 64 68
'''
### 如果不想用本身的列进行分组,还可以额外指定分组
df.groupby([[1,1,1,2,2],['a','a','b','b','c']]).sum()
'''
1 a 72 81 94
b 48 45 47
2 b 33 37 33
c 31 31 43
'''
四. 时间序列
"""时间序列"""
ts = Series(np.arange(10), index = pd.date_range('2018-03-25',periods=10))
'''
2018-03-25 0
2018-03-26 1
2018-03-27 2
2018-03-28 3
2018-03-29 4
2018-03-30 5
2018-03-31 6
2018-04-01 7
2018-04-02 8
2018-04-03 9
Freq: D, dtype: int32
'''
'''
date_range() 参数
start 起始时间
en 结束时间
periods 时间范围(有起始结束则不用设置此参数)
freq 时间间隔 [时间]+[单位] Y年 M月 D天 WOM某个月的某一周
tz 时区
'''
pd.date_range('2018-01-01','2018-01-31',freq='2D')
'''
DatetimeIndex(['2018-01-01', '2018-01-03', '2018-01-05', '2018-01-07',
'2018-01-09', '2018-01-11', '2018-01-13', '2018-01-15',
'2018-01-17', '2018-01-19', '2018-01-21', '2018-01-23',
'2018-01-25', '2018-01-27', '2018-01-29', '2018-01-31'],
dtype='datetime64[ns]', freq='2D')
'''
# https://www.baidu.com/link?url=vAxHkSs07PZqNJR-gd64D-1WjPwhgsRMDmMtc51dy4qJjHvWDFzAst2ksPmhiVEK&wd=&eqid=e51a12da00098bd7000000065c218a9d
ts.resample('3D').sum() # 每三天合并一组,resample只能用于时间格式序列的数据
'''
2018-03-25 3
2018-03-28 12
2018-03-31 21
2018-04-03 9
Freq: 3D, dtype: int32
'''
五. 文件读写
'''读写'''
# 写csv文件
df.to_csv('a.txt') # 第一行为column,第一列为index
df.to_csv('a.txt', header=None) # 不要column名了
# 读
read_df = pd.read_csv('a.txt',header=None)
pd.read_table('a.txt',sep=',')