一.Pandas简介
Pandas(Python Data Analysis Library)基于Numpy构建,让基于Numpy的应用更简单,被广泛应用于金融行业,流行的数据分析工具
二.Pandas安装
由于Pandas是python的第三方库,需要另外安装
pip3 install pandas
三.Pandas的数据结构
Pandas主要有两种数据结构:
- 系列(
Series
) - 数据帧(
DataFrame
)
系列(Series
)是能够保存任何类型的数据(整数,字符串,浮点数,Python对象等)的一维标记数组。轴标签统称为索引。
数据帧(DataFrame)是二维数据结构,即数据以行和列的表格方式排列。
数据帧(DataFrame)的功能特点:
- 潜在的列是不同的类型
- 大小可变
- 标记轴(行和列)
- 可以对行和列执行算术运算
四.各个数据结构示例
1.Series
1)创建Series
# coding:utf-8
import pandas as pd
obj = pd.Series([1, 3, 24, 23, 8])
print(obj)
print("--"*10)
print(obj.values)
print("--"*10)
print(obj.index)
print("--"*10)
print(obj[3])
0 1 1 3 2 24 3 23 4 8 dtype: int64 -------------------- [ 1 3 24 23 8] -------------------- RangeIndex(start=0, stop=5, step=1) -------------------- 23
2)自定义index,定义索引后,原有位置索引依然可以使用
obj = pd.Series([1, 3, 24, 23, 8],index=list("abcde")) print(obj) print("--"*10) print(obj.values) print("--"*10) print(obj.index) print("--"*10) print(obj[3],obj["d"])
a 1 b 3 c 24 d 23 e 8 dtype: int64 -------------------- [ 1 3 24 23 8] -------------------- Index(['a', 'b', 'c', 'd', 'e'], dtype='object') -------------------- 23 23
也可以重新索引,如果某个索引值当前不存在,就引入缺失值“NaN”,
obj = pd.Series([1, 3, 24, 23, 8],index=list("abcde")) obj2=obj.reindex(['b','c','d','f','g']) print(obj2) print("--"*10) print("obj:{}".format(obj.values)) print("obj2:{}".format(obj2.values)) print("--"*10) print(obj2.index) print("--"*10) print(obj2[3],obj2["d"])
b 3.0 c 24.0 d 23.0 f NaN g NaN dtype: float64 -------------------- obj:[ 1 3 24 23 8] obj2:[ 3. 24. 23. nan nan] -------------------- Index(['b', 'c', 'd', 'f', 'g'], dtype='object') -------------------- nan 23.0
对于缺失值,可以填充其他值
obj = pd.Series([1, 3, 24, 23, 8],index=list("abcde")) obj2=obj.reindex(['b','c','d','f','g'],fill_value=0) print(obj2) print("--"*10) print("obj:{}".format(obj.values)) print("obj2:{}".format(obj2.values)) print("--"*10) print(obj2.index) print("--"*10) print(obj2[3],obj2["d"])
b 3 c 24 d 23 f 0 g 0 dtype: int64 -------------------- obj:[ 1 3 24 23 8] obj2:[ 3 24 23 0 0] -------------------- Index(['b', 'c', 'd', 'f', 'g'], dtype='object') -------------------- 0 23
3)使用字典创建Series,字典key会作为series的索引
dic={'calvin':7,'kobe':24,'mj':23,'kd':35} print(pd.Series(dic)) ##### calvin 7 kd 35 kobe 24 mj 23 dtype: int64
2.DataFrame
在所有操作之前当然要先import必要的pandas库,因为pandas常与numpy一起配合使用,所以也一起import吧。对于numpy这个包后面再来写,先导入,看代码,开始这次的重点
1)直接创建,可以直接使用pandas的DataFrame函数创建,比如接下来我们随机创建一个4*4的DataFrame。上面提到过,DataFrame是二维数据结构
# coding:utf-8 import pandas as pd import numpy as np df1=pd.DataFrame(np.random.randn(4,4),index=list('ABCD'),columns=list('ABCD')) print("=="*50) print(df1) print("=="*50) print(df1.ndim) print("=="*50) print(df1.size) print("=="*50) print(df1.shape)
结果:
==================================================================================================== A B C D A -0.077428 1.117524 0.595675 -0.247774 B 0.734320 2.117861 1.531927 -0.485774 C 1.126023 -0.640626 0.755659 -0.651486 D -0.008357 -0.582401 -0.908435 0.225568 ==================================================================================================== 2 #ndim查看DataFrame的"轴",轴为2,即为2维 ==================================================================================================== 16 #size查看DataFrame的数据量,16个数据 ==================================================================================================== (4, 4) #shape查看DataFrame的类型,即4行4列
其中第一个参数是存放在DataFrame里的数据,第二个参数index就是之前说的行名(或者应该叫索引?),第三个参数columns是之前说的列名。
后两个参数可以使用list输入,但是注意,这个list的长度要和DataFrame的大小匹配,不然会报错。当然,这两个参数是可选的,你可以选择不设置。
而且发现,这两个list是可以一样的,但是每行每列的名字在index或columns里要是唯一的。
2)使用字典创建,
dic1 = { 'name': ['小明', '小红', '狗蛋', '铁柱'], 'age': [17, 20, 5, 40], 'gender': ['男', '女', '女', '男'] } df3 = pd.DataFrame(dic1,) print(df3) #### age gender name 0 17 男 小明 1 20 女 小红 2 5 女 狗蛋 3 40 男 铁柱
3.DataFrame查看与筛选数据
3.1 查看列的数据类型,dtypes
df3 = pd.DataFrame(dic1,) print(df3.dtypes) ########## age int64 gender object name object dtype: object
3.2 查看DataFrame的头尾head(),tail()默认都是5行
df4=pd.DataFrame(np.random.randn(6,6)) print(df4.head()) print("--"*50) print(df4.tail(2)) ####### 0 1 2 3 4 5 0 1.343776 -1.279881 -1.181201 -0.396298 -1.125743 -0.611221 1 0.948905 -0.345690 -1.790776 1.020443 -1.254210 -2.217274 2 -0.528329 -0.972449 -0.851321 0.260332 -0.189709 -1.215085 3 -0.520668 1.463702 1.161444 0.734592 -0.766386 0.911954 4 -0.091497 2.277969 -0.596919 1.223075 0.701117 1.179839 ---------------------------------------------------------------------------------------------------- 0 1 2 3 4 5 4 -0.091497 2.277969 -0.596919 1.223075 0.701117 1.179839 5 1.274698 0.056263 -0.244694 0.841284 -0.596790 -1.340147
3.3 查看DataFrame的行名与列名df1.index、df3.columns
df1 = pd.DataFrame(np.random.randn(4, 4), index=list('abcd'), columns=list('ABCD')) print(df1) print("--"*50) print(df1.index) print(df1.columns) ###### A B C D a 0.554493 0.952188 1.506555 -0.618873 b 0.255190 0.357644 0.002479 -0.307104 c -0.283515 0.220664 -0.458655 0.830601 d -0.608960 -0.301327 0.400476 0.118921 ---------------------------------------------------------------------------------------------------- Index(['a', 'b', 'c', 'd'], dtype='object') Index(['A', 'B', 'C', 'D'], dtype='object')
3.4 查看DataFrame的值, values。返回的是一个数组。
dic1 = { 'name': ['小明', '小红', '狗蛋', '铁柱'], 'age': [17, 20, 5, 40], 'gender': ['男', '女', '女', '男'] } df3 = pd.DataFrame(dic1,) print(df3) print("--"*50) print(df3.values) ##### age gender name 0 17 男 小明 1 20 女 小红 2 5 女 狗蛋 3 40 男 铁柱 ---------------------------------------------------------------------------------------------------- [[17 '男' '小明'] [20 '女' '小红'] [5 '女' '狗蛋'] [40 '男' '铁柱']]
查看某一列的数据
dic1 = { 'name': ['小明', '小红', '狗蛋', '铁柱'], 'age': [17, 20, 5, 40], 'gender': ['男', '女', '女', '男'] } df3 = pd.DataFrame(dic1,) print(df3) print("--"*30) print(df3["name"]) print("--"*30) print(df3["name"].values) ###### age gender name 0 17 男 小明 1 20 女 小红 2 5 女 狗蛋 3 40 男 铁柱 ------------------------------------------------------------ 0 小明 1 小红 2 狗蛋 3 铁柱 Name: name, dtype: object ------------------------------------------------------------ ['小明' '小红' '狗蛋' '铁柱']
使用loc或者iloc查看数据值(但是好像只能根据行来查看?)。区别是loc是根据行名,iloc是根据数字索引(也就是行号)。
df1 = pd.DataFrame(np.random.randn(4, 4), index=list('abcd'), columns=list('ABCD')) print(df1.loc["a"]) ------- A -0.224071 B 0.183044 C 0.769312 D 0.700409 Name: a, dtype: float64
或者这样。
df1 = pd.DataFrame(np.random.randn(4, 4), index=list('abcd'), columns=list('ABCD')) print(df1.iloc[0]) ------ A -0.193388 B -0.552667 C 0.368871 D -1.143332 Name: a, dtype: float64
3.5 查看行列数,shape查看行列数,参数为0表示查看行数,参数为1表示查看列数。
dic1 = { 'name': ['小明', '小红', '狗蛋', '铁柱'], 'age': [17, 20, 5, 40], 'gender': ['男', '女', '女', '男'] } df3 = pd.DataFrame(dic1, ) print(df3) print("--" * 50) print("行数:{},列数:{}".format(df3.shape[0], df3.shape[1])) print("类型:%s * %s" % df3.shape) ###### age gender name 0 17 男 小明 1 20 女 小红 2 5 女 狗蛋 3 40 男 铁柱 ---------------------------------------------------------------------------------------------------- 行数:4,列数:3 类型:4 * 3
3.5 小结。
data = {'name': ['calvin', 'kobe', 'michale', 'durant', 'james'], 'age': [29, 40, 56, 30, 34], 'height': [1.70, 1.98, 1.98, 2.06, 2.03]} # 从字典创建DataFrame data2 = [['a', 1], ['b', 2], ['c', 3]] # 从列表创建DataFrame data3 = {'one': pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two': pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])} # 从系列的字典来创建DataFrame dd = pd.DataFrame(data3) df = pd.DataFrame(data2, columns=['name', 'age']) # 加入列标签 dd['three'] = pd.Series([10, 20, 30], index=['a', 'b', 'c']) # 增加列
print(pd.DataFrame(data)) ## age height name 0 29 1.70 calvin 1 40 1.98 kobe 2 56 1.98 michale 3 30 2.06 durant 4 34 2.03 james
print(df) ### name age 0 a 1 1 b 2 2 c 3
print(dd) ### one two three a 1.0 1 10.0 b 2.0 2 20.0 c 3.0 3 30.0 d NaN 4 NaN
print(dd['one']) # 列选择 ### **************************************** a 1.0 b 2.0 c 3.0 d NaN Name: one, dtype: float64 **************************************** print(dd.loc['b']) # 行选择(标签选择) **************************************** one 2.0 two 2.0 three 20.0 Name: b, dtype: float64 **************************************** print(dd.iloc[1]) # 行选择(按整数位置选择) **************************************** one 2.0 two 2.0 three 20.0 Name: b, dtype: float64 **************************************** print(dd[0:2]) # 行切片 **************************************** one two three a 1.0 1 10.0 b 2.0 2 20.0 ****************************************
下表列出了DataFrame构造函数所能接受的各种数据:
类型 |
说明 |
二维ndarray |
数据矩阵,还可以传入行标和列标 |
由数组、列表或元组组成的字典 |
每个序列会变成DataFrame的一列。所有序列的长度必须相同 |
Numpy的结构化/记录数组 |
类似于“由数组组成的字典” |
由Series组成的字典 |
每个Series会成为一列。如果没有显示指定索引,则各Series的索引会被合并成结果的行索引 |
由字典组成的字典 |
各内层字典会成为一列。键会被合并成结果的行索引,跟“由Series组成的字典”的情况一样 |
字典或Series的列表 |
各项将会成为DataFrame的一行。字典键或Series索引的并集将会成为DataFrame的列标 |
由列表或元组组成的列表 |
类似于“二维ndarray” |
另一个DataFrame |
该DataFrame的索引将会被沿用,除非显式指定了其他索引 |
Numpy的MaskedArray |
类似于“二维ndarray”的情况,只是掩码值在结果DataFrame会变成NA/缺失值 |
五.读取Excel文件&CSV文件
新建一个测试用的Excel,命名为
test.xlsx
并加入一些数据,放入到pycharm工程目录下,数据如下图:
import pandas as pd data=pd.read_excel("test.xlsx") print(data.head(3)) #读取前三行数据 ======================================== Date Open Hight Low Close Adj Close Volume 0 2019-10-09 50.123456 75.123456 20.123456 33.123456 43.123456 45.123456 1 2019-10-10 51.123456 76.123456 21.123456 34.123456 44.123456 46.123456 2 2019-10-11 52.123456 77.123456 22.123456 35.123456 45.123456 47.123456 ======================================== print(data.tail(3)) #读取后三行数据 ======================================== Date Open Hight ... Close Adj Close Volume 23 2019-11-01 73.123456 98.123456 ... 56.123456 66.123456 68.123456 24 2019-11-02 74.123456 99.123456 ... 57.123456 67.123456 69.123456 25 2019-11-03 75.123456 100.123456 ... 58.123456 68.123456 70.123456 [3 rows x 7 columns] ======================================== print(data.describe()) #数据概要统计 ======================================== Open Hight Low Close Adj Close Volume count 26.000000 26.000000 26.000000 26.000000 26.000000 26.000000 mean 62.623456 87.623456 32.623456 45.623456 55.623456 57.623456 std 7.648529 7.648529 7.648529 7.648529 7.648529 7.648529 min 50.123456 75.123456 20.123456 33.123456 43.123456 45.123456 25% 56.373456 81.373456 26.373456 39.373456 49.373456 51.373456 50% 62.623456 87.623456 32.623456 45.623456 55.623456 57.623456 75% 68.873456 93.873456 38.873456 51.873456 61.873456 63.873456 max 75.123456 100.123456 45.123456 58.123456 68.123456 70.123456 ========================================
import pandas as pd import matplotlib.pyplot as plt data=pd.read_excel("test.xlsx") #使用日期做索引 dates=pd.to_datetime(data['Date']) df=data.set_index(dates) df.drop('Date',1,inplace=True) df['Open'].plot() plt.show() #显示图片
#访问某列 print(df['Close']) #切片,获取指定的行 print(df['2018-08-08':'2018-08-18']) #索引切片 print(df.loc['2018-08-09',['Open','Close']]) #两个维度切片 print(df.loc['2018-08-09','Open']) #查看2018-08-09这个日期的Open值 print(df.loc['2018-08-02':'2018-08-06','Close']) #查看2018-08-02到2018-08-06之间的Close值 print(df.loc['2018-08-04':'2018-08-08',['Open','Close']]) #查看2018-08-02到2018-08-06之间的Open值和Close值 #位置切片 print(df.iloc[0,:]) #查看第一条数据 print(df.iloc[-5:,:])#获取倒数五条数据 print(df.iloc[-20:-10:4]) #步长为4,获取倒数20行到倒数10行的数据 print(df.iloc[0,0]) #获取第一条的第一个数据 print(df.at[dates[0],'Close']) #获取第一个日期的Close值 print(df[df['Open']>60]) #筛选数据,获取Open值大于60的数据 df['Fake']=pd.Series(np.random.randn(len(df)),index=dates) #增加一列数据 print(df) df2=df.copy() #拷贝一个df2 df2[df2<0]=np.nan #小于0的全部设为NAN print(df2) print(df.mean()) #每一列的平均值 print(df.mean(1)) #每一行的平均值 print(df.groupby(by=df.index.year).mean()) #以年分组,求各年份的平均值 print(df.sort_values(by='Open',ascending=False)) #默认升序排序,ascending=False设置降序排列 #批量迭代读取csv data2=pd.read_csv('test.csv',iterator=True,chunksize=10000,usecols=['date']) print(data2.get_chunk(4)) #获取前四行的数据 print(data2) #显示一串字符串 <pandas.io.parsers.TextFileReader object at 0x004CC490> for i in data2: #迭代读取csv的数据 print(i)