pandas
安装方法:pip3 install pandas
pandas是一个强大的Python数据分析的工具包,它是基于NumPy构建的模块。
pandas的主要功能:
具备对其功能的数据结构DataFrame、Series
集成时间序列功能
提供丰富的数学运算和操作(实质是NumPy提供的)
灵活处理缺失数据(NaN)
引用方法:import pandas as pd
Series
Series是一种类似于一维数组的对象,由一组数据和一组与之相关的数据标签(索引)组成。索引可以自定义如果不谢的话默认是从0开始的数据
1.1、创建方式:
pd.Series([4,7,-5,3]) pd.Series([4,7,-5,3],index=[‘a‘,‘b‘,‘c‘,‘d‘]) pd.Series({‘a‘:1, ‘b‘:2}) pd.Series(0, index=[‘a‘,‘b‘,‘c‘,‘d‘])
1.2、Series比较像列表(数组)和字典的结合体,取Series中某值的话,通过索引可以取值也可以通过位置取值。
In [1]: import pandas as pd #创建Series In [2]: a = pd.Series([11,12,13,14,15],index=list("abcde")) In [3]: a Out[3]: a 11 b 12 c 13 d 14 e 15 dtype: int64 #取值,通过索引(标签)获取 In [4]: a["a"] Out[4]: 11 #通过位置获取 In [5]: a[0] Out[5]: 11
1.3、获取值数组和索引数组:values属性和index属性
In [6]: a Out[6]: a 11 b 12 c 13 d 14 e 15 dtype: int64 #获取左侧索引(标签) In [8]: a.index Out[8]: Index([‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘], dtype=‘object‘) #获取右侧值 In [9]: a.values Out[9]: array([11, 12, 13, 14, 15], dtype=int64)
1.4、Series特性 (完全继承数组NumPy的特性,唯一不同的是:Series是一维数组)
Series支持NumPy模块的特性(下标)
从ndarray创建Series:Series(arr)
与标量运算:sr*2
两个Series运算:sr1+sr2
索引:sr[0], sr[[1,2,4]](花式索引)布尔索引
布尔值过滤:sr[sr>0]
切片:sr[0:2]
也可以通过标签改值:sr[0] = 11
注意:普通的切片也是一个视图,与NumPy中切片的属性完全一致。
通用函数:np.abs(sr)
示例代码:
In [11]: import numpy as np In [12]: import pandas as pd In [13]: a = pd.Series(np.arange(6),index=list("abcdef")) In [14]: a Out[14]: a 0 b 1 c 2 d 3 e 4 f 5 dtype: int32 #标量运算测试 In [15]: a+1 Out[15]: a 1 b 2 c 3 d 4 e 5 f 6 dtype: int32 In [16]: a**2 Out[16]: a 0 b 1 c 4 d 9 e 16 f 25 dtype: int32 In [17]: a+a Out[17]: a 0 b 2 c 4 d 6 e 8 f 10 dtype: int32 #索引取值 In [18]: a[0] Out[18]: 0 In [19]: a[-1] Out[19]: 5 #花式索引取值 In [20]: a[[1,2,4]] Out[20]: b 1 c 2 e 4 dtype: int32 #布尔索引判断 In [21]: a>3 Out[21]: a False b False c False d False e True f True dtype: bool #布尔索引取值 In [22]: a[a>3] Out[22]: e 4 f 5 dtype: int32 #切片 In [23]: b = a[:3] In [24]: b Out[24]: a 0 b 1 c 2 dtype: int32 #切片视图测试 In [25]: b[0]=10 In [26]: b Out[26]: a 10 b 1 c 2 dtype: int32 In [27]: a Out[27]: a 10 b 1 c 2 d 3 e 4 f 5 dtype: int32 #切片拷贝测试 In [28]: c = a[3:].copy() In [29]: c Out[29]: d 3 e 4 f 5 dtype: int32 In [30]: c[-1]=15 In [31]: c Out[31]: d 3 e 4 f 15 dtype: int32 In [32]: a Out[32]: a 10 b 1 c 2 d 3 e 4 f 5 dtype: int32 #通用函数测试 In [34]: a[0] = -10 In [35]: a Out[35]: a -10 b 1 c 2 d 3 e 4 f 5 dtype: int32 In [36]: np.abs(a) Out[36]: a 10 b 1 c 2 d 3 e 4 f 5 dtype: int32
1.5、Series支持字典的特性(标签):
可以通过字典创建Series:
dic = {"a":1,"b":2,"c":3}
pd.Series(dic),
in运算,判断键在不在Series中,返回布尔值。get也可以判断,但不会报错!
’a’ in sr
键索引:sr[‘a‘], sr[[‘a‘, ‘b‘, ‘d‘]],也支持切片
当用标签去切片的时候,是可以取到结果的!原因:数组是有序的!并且切片得到的结果不同于数组的切片是顾头顾尾!
不同点:for 循环得到的是values值而不是索引!可以理解为数组的权重高!
示例代码:
In [37]: dic = {"a":1,"b":2,"c":3} #通过字典创建Series数据 In [38]: a = pd.Series(dic) In [39]: a Out[39]: a 1 b 2 c 3 dtype: int64 #in判断 In [40]: "a" in a Out[40]: True In [41]: "d" in a Out[41]: False #切片 #通过标签切片 In [42]: a["a":"b"] Out[42]: a 1 b 2 dtype: int64 In [43]: a["b":] Out[43]: b 2 c 3 dtype: int64 #通过索引切片 In [44]: a[:2] Out[44]: a 1 b 2 dtype: int64 #索引与花式索引 In [45]: a["a"] Out[45]: 1 In [46]: a[["a","c"]] Out[46]: a 1 c 3 dtype: int64 #for循环取值 In [47]: for i in a: ...: print(i) ...: 1 2 3
1.6、整数索引:
大家都知道,切片的时候中括号中可以放标签也可以放下标;如果标签是整数,通过切片方式获取值的话,当数值既可以解释成标签也可以解释成下标的时候,他会解释成标签所以最好避免这种以数字作为索引(标签)的方式!要不然会产生各种误会!
可以通过两个属性来解决这个问题:
loc 默认通过标签形式解释
iloc 默认是以下标形式解释
注意:loc or iloc 可以传一个值,也可以切片
示例代码:
#生成Series数组对象 In [48]: b = pd.Series(np.arange(10,20),index=np.arange(10,20)) In [49]: b Out[49]: 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 dtype: int32 #通过下标获取 In [50]: b[0] ------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-50-422167f1cdee> in <module>() ----> 1 b[0] c:\program files\python36\lib\site-packages\pandas\core\series.py in __getitem__(self, key ) 599 key = com._apply_if_callable(key, self) 600 try: --> 601 result = self.index.get_value(self, key) 602 603 if not is_scalar(result): c:\program files\python36\lib\site-packages\pandas\core\indexes\base.py in get_value(self, series, key) 2475 try: 2476 return self._engine.get_value(s, k, -> 2477 tz=getattr(series.dtype, ‘tz‘, None)) 2478 except KeyError as e1: 2479 if len(self) > 0 and self.inferred_type in [‘integer‘, ‘boolean‘]: pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_value (pandas\_libs\index.c:4 404)() pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_value (pandas\_libs\index.c:4 087)() pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_loc (pandas\_libs\index.c:512 6)() pandas\_libs\hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item (pandas\_libs\hashtable.c:14031)() pandas\_libs\hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item (pandas\_libs\hashtable.c:13975)() KeyError: 0 #通过下标切片获取 In [51]: b[-2:] Out[51]: 18 18 19 19 dtype: int32 #通过标签上的数字 In [52]: b[10] Out[52]: 10 In [53]: b[19] Out[53]: 19 #但无法完成切片 In [54]: b[10:15] Out[54]: Series([], dtype: int32) In [60]: b Out[60]: 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 dtype: int32 #同过loc和iloc获取 In [61]: b.loc[10] Out[61]: 10 In [63]: b.loc[19] Out[63]: 19 In [64]: b.iloc[0] Out[64]: 10 In [65]: b.iloc[-1] Out[65]: 19
1.7、Series数据对齐 (常用运算)
【Series在计算时,会先按照标签对齐,然后才会计算】
pandas在运算时,会按索引进行对齐然后计算。如果存在不同的索引,则结果的索引是两个操作数索引的并集。
sr1 = pd.Series([12,23,34], index=[‘c‘,‘a‘,‘d‘]) sr2 = pd.Series([11,20,10], index=[‘d‘,‘c‘,‘a‘,]) sr1+sr2 sr3 = pd.Series([11,20,10,14], index=[‘d‘,‘c‘,‘a‘,‘b‘]) sr1+sr3
所以当两个Series的标签不同时,第一步会先合并标签,然后在计算时会把不同标签的值写成NaN(缺失值),原标签对应的值就不存在。这是因为在进行计算的时候,不同的标签只有一个值,当他与一个缺失标签进行计算的话就会变成缺失值。
那如何在两个Series对象相加时将缺失值设为0呢?在做不同运算的时候,添加相关参数:fill_value=0;定义默认缺失标签值为0
sr1.add(sr2, fill_value=0)
灵活的算术方法:add, sub, div, mul
示例代码:
#定义两个Series数组对象 In [68]: sr1 = pd.Series([12,23,34], index=[‘c‘,‘a‘,‘d‘]); In [69]: sr2 = pd.Series([11,20,10], index=[‘d‘,‘c‘,‘a‘,]) #查看数据 In [70]: sr1 Out[70]: c 12 a 23 d 34 dtype: int64 In [71]: sr2 Out[71]: d 11 c 20 a 10 dtype: int64 #数据对齐加法计算 In [72]: sr1+sr2 Out[72]: a 33 c 32 d 45 dtype: int64 #在定义另一个Series对象 In [73]: sr3 = pd.Series([11,20,10,14], index=[‘d‘,‘c‘,‘a‘,‘b‘]) #查看 In [74]: sr3 Out[74]: d 11 c 20 a 10 b 14 dtype: int64 ##数据对齐加法计算(标签并集,缺失值) In [75]: sr1+sr3 Out[75]: a 33.0 b NaN c 32.0 d 45.0 dtype: float64 #解决标签对应缺失值问题 In [76]: sr1.add(sr3,fill_value=0) Out[76]: a 33.0 b 14.0 c 32.0 d 45.0 dtype: float64
1.8、Series关于缺失数据
【注意pandas是不会在原来的数据上修改,需要接收修改覆盖掉,或是重新接收】
缺失数据:使用NaN(Not a Number)来表示缺失数据。其值等于np.nan。内置的None值也会被当做NaN处理。
缺失值表示方式:na nan NaN null
处理缺失数据的相关方法:
dropna() 过滤掉值为NaN的行
fillna() 填充缺失数据
isnull() 返回布尔数组,缺失值对应为True
notnull() 返回布尔数组,缺失值对应为False
过滤缺失数据:sr.dropna() 或 sr[sr.notnull()]
填充缺失数据:sr.fillna(0)
判断是缺失值的方法:sr.isnull() 返回是布尔值的数组,缺失值对应为True
判断不是缺失值的方法:sr.notnull() 返回是布尔值的数组,缺失值对应为False
处理缺失数据有两种办法:
一种是去除不再需要:sr = sr.dropna();
另一种是填上默认值: sr.fillna(1) 用某值把NaN填上参数
示例代码:
In [78]: d Out[78]: a 33.0 b NaN c 32.0 d 45.0 dtype: float64 #去除缺失值 In [79]: d.dropna() Out[79]: a 33.0 c 32.0 d 45.0 dtype: float64 #缺失值判断 In [80]: d.isnull() Out[80]: a False b True c False d False dtype: bool #非缺失值判断 In [81]: d.notnull() Out[81]: a True b False c True d True dtype: bool #缺失值填充 In [82]: d.fillna(111) Out[82]: a 33.0 b 111.0 c 32.0 d 45.0 dtype: float64
NumPy中的通用函数,Series全部支持!
DataFrame
DataFrame是一个表格型的数据结构,含有一组有序的列,要求每一列的数据类型必须相同。DataFrame可以被看做是由Series组成的字典,并且共用一个Series的索引。
2.1、创建方式(很多种,以字典类型举例):
pd.DataFrame({‘one‘:[1,2,3,4],‘two‘:[4,3,2,1]}) pd.DataFrame({‘one‘:pd.Series([1,2,3],index=[‘a‘,‘b‘,‘c‘]), ‘two‘:pd.Series([1,2,3,4],index=[‘b‘,‘a‘,‘c‘,‘d‘])}) ……
列索引就是创建时字典的键,行索引就是Series的标签;创建的时候还是需要数据对齐的问题!!!
2.2、csv文件读取与写入:
pd.read_csv(‘filename.csv‘) #读取 传值可以是文件对象,可以是文件名; pd.to_csv() #写入 存储文件的时候,会默认把标签列存入,所以存储的时候需要处理下,指定不存储索引。 csv格式存储数据,所有的数据都是以逗号隔开;python内置有处理csv文件的库
2.3、DataFrame查看数据
查看数据常用属性及方法:
index 获取行索引 T 转置 【行列互换】 columns 获取列索引 values 获取值 【二维数组,一行代表一条】 describe() 快速统计 【按列打印的统计描述信息】
name属性:(df 是 DataFrame 对象简写。)
DataFrame 对象每一列都会有一个name属性,就是每列的id名。
1、索引(标签)列的id名:
df.index.name # 查看id df.index.name = "###" #给索引列添加或是改名
2、DataFrame各列name属性:
对列改名:df.rename(columns={"原列名":"新列名",.....})
2.4、DataFrame索引和切片
DataFrame是结合了NumPy和series的所有方法,所以他具有各种各样的花式索引。不同的是:DataFrame有行索引和列索引。
注意:
1、df[] 只能选列,不能选行(直接索引,花式索引都可以,切片不行);如果选择的仅一列可以看作是Series去操作
2、df[]通过索引得到的数据还是DataFrame对象。
3、df[0:10]如果直接切片操作,DataFrame对象会解释为行,这之后也可以使用列的花式索引!
4、不建议使用上述方法去切片,如果要取一个值的话,可以使用!
获取数据正确的打开方式是:loc[[行,列]]【标签索引】和iloc[[行下标,列下标]]【下标索引】
df.loc[[:10,["close","open"]]] #获取前10行 close和open列的数据
df.iloc[[:10,:2]]
1.1、通过标签获取: df[‘A‘] #只取单列 df[[‘A‘, ‘B‘]] #取a,b两列 df[‘A‘][0] #取A列上第一个值 df[0:10][[‘A‘, ‘C‘]] #取前10行A、C两列的值 #通过loc属性进行切片操作获取需要的数据 df.loc[:,[‘A‘,‘B‘]] #获取A、B两列 df.loc[:,‘A‘:‘C‘] #切片获取 A、B、C三列 df.loc[0,‘A‘] #获取单个数据 df.loc[0:10,[‘A‘,‘C‘]] ##取前10行A、C两列的值 1.2、通过位置获取:(记住是通过下标去获取的!) df.iloc[3] df.iloc[3,3] df.iloc[0:3,4:6] df.iloc[1:5,:] df.iloc[[1,2,4],[0,3]] 1.3、通过布尔值过滤: df[df[‘A‘]>0] # 通过某一列过滤的数据 df[df<0] #把获取所有为负数的数据 会把所有False对应的值改成NaN,而不是舍去;因为DataFrame是二维数组,无法删除某一行或是某一列。 df[df<0].fillna(0) #给所有NaN的位置赋值为0 df[df[‘id‘].isin([1,3,5])] #isin是在集合中查询,查找某一列中有没有对应值的数据,返回布尔值,然后通过这些值过滤出行。 #同一类型的数据下,可以通过布尔索引过滤,对是NaN的值赋值 df[df["C"]<20] = 0
2.5、DataFrame数据对齐与缺失数据
数据对齐:
DataFrame对象在运算时,同样会进行数据对齐,结果的行索引与列索引分别为两个操作数的行索引与列索引的并集。(数据对齐不仅是列对齐,行也必须对齐!)
DataFrame处理缺失数据的方法【与Series的方法一致】。
dropna(axis=0,where=‘any‘,…) #默认是判断一行中有没有NaN,有的话会把这一行删除。默认对行操作,默认是any #参数解释: # where="any"/"all" any指:这一行中有一个NaN就删除;all指:这一行中全部都是NaN才删除; # axis 指对行还是对列执行删除操作:0代表行,1代表列 fillna() isnull() notnull()
2.6、其他常用方法 (注意数据的类型)
pandas常用方法(适用Series和DataFrame): mean(axis=0,skipna=False) #平均值 sum(axis=1) #求和 sort_index(axis, …, ascending) 按行或列索引排序 #参数: # ascending升序降序,默认为True,改为False为降序 # axis 指行或列,默认为行 sort_values(‘列名‘, axis, ascending) 按值排序/按列排序 #注意点:排序可以传入一个列表,表示按照关键字排序,优先按照第一个元素排序,一样的话再按照第二个排序,依次类推! sort_values(["close","id"])
NumPy的通用函数同样适用于pandas
#参数为函数的方法,把所有的元素都执行一遍这个函数 apply(func, axis=0) 将自定义函数应用在各行或者各列上,func可返回标量或者Series,func可返回标量或者Series applymap(func) 将函数应用在DataFrame各个元素上 map(func) 将函数应用在Series各个元素上 df.applymap(lambda x:x+1) #操作对象是元素 df["close"].map(lambda x:x+1) df.apply(lambda x:x.sum) #默认操作对象为一列数据
2.7、层次化:
就是有多层索引!通过索引一层一层的去获取数据!
层次化索引是Pandas的一项重要功能,它使我们能够在一个轴上拥有多个索引级别。
例:data=pd.Series(np.random.rand(9), index=[[‘a‘, ‘a‘, ‘a‘, ‘b‘, ‘b‘, ‘b‘, ‘c‘, ‘c‘, ‘c‘], [1,2,3,1,2,3,1,2,3]])
2.8、从文件读取
1、读取文件:从文件名、URL、文件对象中加载数据
read_csv 默认分隔符为,[逗号] read_table 默认分隔符为\t
2、读取文件函数主要参数:
sep 指定分隔符,也可以用正则表达式,如:‘\s+‘ header=None 指定文件无列名 (会改成编号0,1,2,3) 不写默认把第一行转换成列名 names 指定列名 names=["列名1","列名2",....]可以指定列名 index_col 指定某列作为索引(行索引) [比其他列名低一格] na_values 指定某些字符串表示缺失值 na_values=["none","None","na","nan","NaN","null"] 把列表内的数据解析成 parse_dates 指定某些列是否被解析为日期,传值是布尔值或列表 转化成时间对象,默认为True skiprows 跳过某几行不读 skiprows=["行索引",...]
3、写入到文件:
写入到文件的方法:to_csv
写入文件函数的主要参数:
sep 指定分隔符, na_rep 指定缺失值转换的字符串,默认为空字符串 header=False 不输出列名一行 index=False 不输出行索引一列 保存文件的时候不保存索引列 cols 指定输出的列,参数传入为列表,元素为列名 其他文件类型:json, XML, HTML, 数据库 pandas转换为二进制文件格式(pickle): save load
2.8、时间对象处理
1、时间序列类型:
时间戳:特定时刻
固定时期:如2017年7月
时间间隔:起始时间-结束时间
Python标准库:datetime 需要指定时间格式
date time datetime timedelta strftime() #对象转成字符串 strptime() #字符串转换成对象
第三方包:dateutil
import dateutil dateutil.parser.parse() #不用指定格式,直接对时间字符串类型转换成时间对象。
成组处理日期:pandas
pd.to_datetime([‘2001-01-01‘, ‘2002-02-02‘])
2、产生时间对象数组:date_range
start 开始时间 end 结束时间 periods 时间长度 给定起始时间(字符串类型),指定时间长度,生成多少天 freq 时间频率,默认为‘D‘,可选H(our),W(eek),B(usiness),S(emi-)M(onth)【半个月】,M(onth),(min)T(es), S(econd), A(year),… W-MON 每周一...可以看文档查找
2.9、时间索引
时间序列就是以时间对象为索引的Series或DataFrame。
datetime对象作为索引时是存储在DatetimeIndex对象中的。
1、时间索引特殊功能:
1)传入“年”或“年月”作为切片方式
df["2017"] #会把2017年的数据全部算出来; df["2017-02"] #会把2017年2月的所有数据取出来
2)传入日期范围作为切片方式
df["2017-01-01":"2017-05-08"] #按照时间切片获取,后包括切片时间内容。