pandas

pandas:数据分析

pandas是一个强大的python数据分析的工具包
pandas是基于numpy构建的
主要功能:
(1)具备其功能的数据结构DataFrame、Series
(2)集成时间序列功能
(3)提供丰富的数学运算和操作
(4)灵活处理缺失数据
安装:pip install pandas
引用:import pandas as pd


pandas:Series
Series是一种类似于一维数组的对象,由一组数据和一组与之相关的数据标签(索引)组成
创建方式:
import pandas as pd
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'])

  获取值数组和索引数组:values,index

  Series比较像列表(数组)和字典的结合体


pandas:Series特性

Series支持数组的特性:
  • 从ndarray创建Series:Series(arr)
  • 与标量运算:sr*2
  • 两个Series运算:sr1+sr2
  • 索引:sr[0],sr[[1,2,4]]
  • 切片:sr[0:2](切片依然是视图形式)
  • 通用函数:np.abs(sr)
  • 布尔值过滤:sr[sr>0]
  • 统计函数:mean() sum() cumsum()
Series支持字典的特性(标签):
(1)从字典创建Series:Series(dic),
(2)in运算:'a'in sr,for x in sr
(3)键索引:sr['a'],sr[['a','b','d']]
(4)键切片:sr['a':'c']
(5)其它函数:get('a',default=0等)

pandas:整体索引
如果索引是整数类型,则根据整数进行数据操作时总是面向标签的
(1)loc属性:以标签解释
(2)iloc属性:以下标解释

数据对齐
(1)pandas在运算时,会按索引进行对齐然后计算,如果存在不同的索引,则结果的
索引是两个操作数索引的并集
(2)例:
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
(3)如何在两个Series对象相加时将缺失值设为0?
sr1.add(sr2,fill_value=0)
灵活的算术方法:add,sub,div,mul

Series缺失数据

缺失数据:使用NaN(Not a Number)来表示缺失数据,其值等于np.nan
内置的None值也会被当做NaN处理
处理缺失数据的相关方法:
dropna() 过滤掉值为NaN的行
fillna() 填充缺失数据
isnull() 返回布尔数组,缺失值对应为True
notnull() 返回布尔数组,缺失值对应为False
过滤缺失数据:sr.dropna()或sr[data.notnull()]
填充缺失数据:fillna(0)

 

示例:

#创建Series
import pandas as pd
(1)
sr = pd.Series(np.array([2,3,-1,5]), index = ['a','b','c','d'])
sr
result:
a    2
b    3
c   -1
d    5
dtype: int32

(2)sr[sr>0]
result:
a    2
b    3
d    5
dtype: int32

(3)
d = {'a':2,'b':3,'c':-1,'d':5}
sr = pd.Series({'a':2,'b':3,'c':-1,'d':5})
sr
result:
a    2
b    3
c   -1
d    5
dtype: int64

(4)
for x in sr.index: #sr.index获取索引
  print(x)
result:
a

b
c
d

(5)sr.values #获取Series的值
result:
array([ 2, 3, -1, 5], dtype=int64)

(6)sr[['a','c']]
result:
a 2
c -1
dtype: int64

(7)sr.get('e',default=0)
result:0

(8)
sr = pd.Series([1,2,3,4,5,6,7])
sr2 = sr[3:].copy()
sr2
result:
3    4
4    5
5    6
6    7
dtype: int64

#loc、iloc属性
(9)sr2.loc[3]
result:4

(10)sr2.iloc[-1]
result:7

#数据对齐
(11)
sr1 = pd.Series([12,23,34], index=['c','a','d'])
sr2 = pd.Series([11,20,10], index=['b','c','a'])
sr1+sr2
result:
a    33.0
b     NaN
c    32.0
d     NaN
dtype: float64     #由于NaN的存在,sr1,sr2的int类型变为了float64类型

#NaN
(12)sr[sr.notnull()] #去掉NaN
result:
a    33.0
c    32.0
dtype: float64

(13)sr = sr.fillna(sr.mean()) #对NaN位置填充平均数
sr
result:
    a    33.0
   b    32.5
   c    32.0
   d    32.5
   dtype: float64
 pandas:DataFrame

  
(1)DataFrame是一个表格型的数据结构,含有一组有序的列
  
(2)DataFrame可以被看做是由Series组成的字典,并且共用一个索引
  (3)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'])})
(4)csv文件读取与写入:
df.read.csv('filename.csv)
df.to_csv()

获取数据:
查看数据常用属性及方法:
index 获取索引
T 转置
columns 获取列索引
values 获取值数组
describe() 获取快速统计

DataFrame各列name属性:列名 rename(columns={})

pandas:DataFrame索引和切片
DataFrame有行索引和列索引
可以通过标签和位置两种方法进行索引和切片

方法1:两个中括号,先取列再取行 df['A'][0]
方法2(推荐):使用loc/iloc属性,一个中括号,逗号隔开,先取行再取列
loc属性:解释为标签
iloc属性:解释为下标
向DataFrame对象中写入值时只使用方法2
行/列索引部分可以带常规索引、切片、布尔值索引、花式索引任意搭配
两部分都是花式索引结果可能与预料的不同

#通过标签取
df['A']
df['a','b']
df['a'][0]
df[0:10][['a','b']]
df.loc[:,['a','b']]
df.loc[0,'a']
df.loc[:,'a':'c']
df.loc[0:10,['a','c']]

#通过位置取
df.iloc[3]
df.iloc[3,3]
df.iloc[0:3,4:6]
df.iloc[1:5,:]
df.iloc[[1,2,4],[0,3]]

#通过布尔值过滤:
df[df['a']>0]
df[df['a'].isin([1,3,5])]
df[df<0]=0

DataFrame数据对齐与缺失数据
(1)DataFrame对象在运算时,同样会进行数据对齐,行索引与列索引分别对齐
(2)结果的行索引与列索引分别为两个操作数的行索引与列索引的并集
(3)DataFrame处理缺失数据的相关方法:
dropna(axis=0,how='any',...)
fillna()
isnull()
notnull()

   示例:
#创建DataFrame
(1)
df = pd.DataFrame({'one':[1,2,3,4],'two':[4,3,2,1]}, index=list('abcd'))
df

 onetwo
a 1 4
b 2 3
c 3 2
d 4 1
(2)df['one']
result:
a    1
b    2
c    3
d    4
Name: one, dtype: int64

(3)pd.DataFrame({'one':pd.Series([1,2,3],index=['a','b','c']),
'two':pd.Series([1,2,3,4],index=['b','a','c','d'])})
result:
 onetwo
a 1.0 2
b 2.0 1
c 3.0 3
d NaN 4

#读文件
(4)
df = pd.read_csv('601318.csv')
df = df.loc[:,'open':'low']
df
result:
 openclosehighlow
0 21.878 20.473 22.302 20.040
1 20.565 20.307 20.758 20.075
2 20.119 19.419 20.202 19.047
3 19.253 19.800 20.128 19.143
4 19.817 20.338 20.522 19.651
5 20.171 20.093 20.272 19.988
                     ......

(5)np.array(df.index)
reault:array([ 0, 1, 2, ..., 2589, 2590, 2591], dtype=int64)

  (6)df.columns
     result:
      Index(['open', 'close', 'high', 'low'], dtype='object')
array([[ 21.878,  20.473,  22.302,  20.04 ],
       [ 20.565,  20.307,  20.758,  20.075],
       [ 20.119,  19.419,  20.202,  19.047],
       ..., 
       [ 79.   ,  76.44 ,  79.44 ,  76.38 ],
       [ 75.93 ,  75.29 ,  75.99 ,  74.8  ],
       [ 75.3  ,  76.1  ,  76.85 ,  75.21 ]])

(8)df.describe()
result:


#loc、iloc属性
(9)
df = pd.DataFrame({'one':[1,2,3,4],'two':[4,3,2,1]}, index=list('abcd'))
df.loc['b',df.colums[1]
#nan,inf
(10)
df2 = df.copy()
df2['close'][df2['close']>20] = np.nan
df2

(11)
df2[df2['close'].notnull()]
result:


(12)df3=df2.T
df3.fillna(0)
result:

pandas常用方法(适用于Series和DataFrame):
     (1)mean(axis=0,skipna=False)
(2)sum(axis=1)
(3)sort_index(axis,...,ascending) #按行或列索引排序
(4)sort_value(by,axis,ascending) #按值排序
(5)NumPy的通用函数同样适用于pandas
(6)apply(func,axis=0) #将自定义函数应用在各行或各列上,func可返回标量或Series
(7)map(func) #将函数应用在Series各个元素上

pandas:时间对象处理
(1)时间序列类型:
时间戳:特定时刻
固定时期:如2017年12月
时间间隔:起始时间-结束时间

(2)python标准库:datetime
date time datetime timedelta
dt.strftime()
strptime()
(3)灵活处理时间对象:dateutil包
     dateutil.parser.parse()
(4)成组处理时间对象:pandas
pd.to_datetime(['2001-01-01','2002-02-02'])
(5) 产生时间对象数组:date_range
start 开始时间
end 结束时间
periods 时间长度
freq 时间频率,默认为'D',可选H(our),W(eek),A(year)
B(usiness),S(emis),M(onth),(min)T(es),S(econd)

(6)pandas:时间序列
时间序列就是以时间对象为索引的Series或DataFrame
datetime对象作为索引时存储在DatetimeIndex对象中的
(7)时间序列的特殊功能
传入‘年’或‘年月’作为切片方式
传入日期范围作为切片方式
丰富的函数支持:resample(),strftime(),....
批量转换为datetime对象:to_pydatetime()

pandas:从文件中读取
(1)读取文件:从文件名、url、文件对象中加载对象
read_csv 默认分隔符为,
read_table 默认分隔符为\t
read_excel 读取excel文件

(2)读取文件函数主要参数:
sep 指定分隔符,可用正则表达式如'\s+'
header=None 指定文件无列名,默认为True
name 指定列名
index_col 指定某列作为索引
skip_row 指定跳过某些行
na_values 指定某些字符串表示缺失值
parse_dates 指定某些列是否被解析为日期,布尔值或列表

pandas:写入到文件
写入到文件:to_csv
写入文件函数的主要参数:
sep
no_rep 指定缺失值转换的字符串,默认为空字符串
header=False 不输出列名一行
index=False 不输出行索引一列
cols 指定输出的列,传入列表
其它文件类型:json,xml,HTML,数据库
pandas转换为二进制文件格式(pickle):
save load

pandas:数据分组与聚合

(1)在数据分析中,我们有时需要将数据拆分,在每一个特定的组里进行运算
(2)groupby(by=None,...)
(3) df.groupby('key').mean()
(4)分组与聚合的步骤:
分组:拆分数据为若干组
聚合:组内应用某个函数

分组:
(1)分组函数:groupby
(2)不同的分组方法
按一列分组:groupby('key1')
按多列分组:groupby(['key1','key2'])
自定义分组:groupby(len)
(3)获取分组信息
groups
get_group('a')
for name,group in df.groupby('key')

聚合:
(1)数据合并:拼接(concatenate)、连接(join)
(2)数据拼接:
pd.concat([df1,df2,df3])
pd.concat([df1,df2,df3],keys=['a','b','c'])
pd.concat([df1,df2,df3],axis=1)
pd.concat([df1,df2,df3],ignore_index=True)
(3)数据连接:
pd.merge(df1,df2,on='key')
pd.merge(df1,df2,on=['key1','key2'])
        pd.merge(df1,df2,on='key',how='inner')
how:inner,outer,left,right

 

示例:
#通用函数
(1)df2.mean() #求平均
result:
open     27.466931
close    17.428191
high     27.942482
low      27.061332
dtype: float64

(2)df2.sort_index(ascending=False) #倒序排
result:
       
(3)df3.sort_index(axis=1, ascending=False)
result:

(4)df2.sort_values('close') #按指定字段排序
result:

(5)df.apply(lambda x:pd.Series([(x['high'] + x['low'])/2 ,(x['open'] + x['close'])/2],
index=['hl_mean','oc_mean']), axis=1) #可以拿出部分数据重新组成数组
result:

(6)df.applymap(lambda x:x+1) #对数据在原有的基础上增删改

改之前 改之后


(7)df+1 #也可实现 df为原数据

改之前 改之后


(8)import datetime #python datetime模块示例
datetime.datetime.strptime("2018-1-29","%Y-%m-%d")
result:
datetime.datetime(2018, 1, 29, 0, 0)


(9)import dateutil #python pandas模块中的dateutil示例
dateutil.parser.parse("2018-2-8")
  result:datetime.datetime(2018, 2, 8, 0, 0)
(10)arr = pd.to_datetime(['2018-2-8','2017-1-1','1990-2-1']).to_pydatetime()
arr
result:
      array([datetime.datetime(2018, 2, 8, 0, 0),
          datetime.datetime(2017, 1, 1, 0, 0),
          datetime.datetime(1990, 2, 1, 0, 0)], dtype=object)

   (11) df.index = pd.date_range('2010-1-1',periods=len(df),freq='B')     #只显示工作日数据

        df

     result:
          
 
  (12)df["2016-03":"2017-05-03"]    #查看2016-03到2017-05-03之间的数据,对时间切片
 
  (13)df.index.strftime('%Y-%m-%d')
      result:
      array(['2010-01-01', '2010-01-04', '2010-01-05', ..., '2019-12-05',
       '2019-12-06', '2019-12-09'],dtype='<U10')
 
 (14) df = pd.read_csv('601318.csv')     #读取文件数据
 
 (15)pd.read_table('601318.csv',sep=',')  #读取文件中的数据,以逗号隔开
 
  (16)pd.read_excel('601318.xlsx')         #读取excel数据
 
  (17)df = pd.read_csv('601318.csv', header=None)    #读取.csv文件数据,且第一行不显示出来

       df = df.rename(columns={0:'a',1:'b'})           #对列标签命名

       

 

       df  

 

       

 

       result:

 

        

 

               

 

   

 

 

 

    

 

       
   (18)df = pd.read_csv('601318.csv', header=None, names=list('asdfghjk'))  不显示第一行,且对列标签命名
       df
    result:

 

 

             
 
   (19)  df = pd.read_csv('601318.csv',index_col=1, parse_dates=['date'])   #指定第一列作为索引,且解析为日期
         df
     result
             
 
   (20)  #指定第一列作为索引,且解析为日期,同时为None的数据用NaN代替 
      df = pd.read_csv('601318.csv',index_col=1, parse_dates=['date'],na_values=['None'])  
         df['volume']
      result
               
 
    (21)df = pd.DataFrame({'data1':np.random.uniform(10,20,5),'data2':np.random.uniform(-10,10,5),       

            'key1':list('abbab'),'key2':list('fgfgf')}, index=['Alex','Bob','Celina','Debi','Egon'])      #随机创建二维数组
        df

        result:

         

    (22)df2 = df.groupby(['key1','key2']).mean()     #先以key1分组之后,再分别对key2分组求平均

        df2

        result

              

     (23)df.groupby('key1').sum()

         result:

              

     (24)df.groupby(lambda x:'zheng' if df.loc[x,'data2']> 0 else 'fu').mean()      #以data2正负分组,求平均

         result

               

 

     (25) df.groupby('key1').get_group('b')     #拿出key1为b的数据
          result
           
      (26)for name, group in df.groupby('key1'):    #以key1分组,分别打印每组数据
          print(group)
           result:
               
 
     (27)以key1分组之后的data1和data2的最大值减去最小值

       df.groupby('key1').max()[['data1','data2']] - df.groupby('key1').min()[['data1','data2']]  

      df.groupby('key1').agg(lambda x:x.max()-x.min())
     
         result:
               
 
   (28)df.groupby('key1').agg({'data1':'min', 'data2':'max'})         #以key1分组之后,data1的最小值,data2的最大值
         result:
                
     (29)df0 = pd.read_csv('601318.csv') 
           df0.resample('3W').mean()           #对数据重新采样,3周一采样,求3周的平均值
      result:
                
 
    (30)  df = pd.DataFrame({'data1':np.random.uniform(10,20,5),'data2':np.random.uniform(-10,10,5),
              'key1':list('abbab'),'key2':list('fgfgf')}, index=['Alex','Bob','Celina','Debi','Egon'])

      df2 = df.copy()
      df3 = df.copy()

      pd.concat([df,df2,df3],ignore_index=True)        #拼接表格,ignore_index表示两个表的index没有实际含义,根据列字段对齐,然后合并

         result:
                
 
     (31)pd.concat([df,df2,df3],axis=1, ignore_index=True)   #拼接表格,ignore_index表示两个表的index没有实际含义,根据行字段对齐,然后合并  
     result:
                 
 
    (32) pd.merge(df,df2, on=['key1','key2'])           #用key1、key2将df、df2连接起来
      result:
                
 
    (33)df.loc['Celina','key1'] = 'd'       将'Celina'的'key1'索引改为d,df2不发生变化
        df
     result
                
  (34)pd.merge(df,df2,on='key1',how='outer')
       result:
             
 
    

 

 

 

 

 

posted @ 2018-02-05 18:54  星雨5213  阅读(142)  评论(0)    收藏  举报