Pandas简介

一、什么是Pandas

当大家谈论到数据分析时,提及最多的语言就是Python和SQL

而Python之所以适合做数据分析,就是因为他有很多强大的第三方库来协助

pandas就是其中之一,它是基于Numpy构建的,正因pandas的出现,让Python语言也成为使用最广泛而且强大的数据分析环境之一。

如果说没有pandas的出现,目前的金融数据分析领域还应该是R语言的天下。

二、Pandas能干什么

1.具备对应其功能的数据结构DataFrame,Series
2.集成时间序列功能
3.提供丰富的数学运算和操作
4.灵活处理缺失数据
.....

以上就是pandas能完成的一些基础操作,当然并不完全,下面就来看看pandas到底是怎么用的。

三、怎么用Pandas

安装

pip install pandas

引用

import pandas as pd

四、Pandas基础使用

Series

Series是一种类似于一维数组的对象,由一组数据和一组与之相关的数据标签(索引)组成。在数据分析的过程中非常常用。

1. 创建方法

import pandas as pd

1.直接传列表的形式,创建pandas数据
pa1 = pd.Series([1,2,3,4,5])
print(type(pa1))
print(pa1)
执行结果如下:
	<class 'pandas.core.series.Series'>
    0    1
    1    2
    2    3
    3    4
    4    5
    dtype: int64
总结:将数组索引以及数组的值打印出来,索引在左,值在右,由于没有为数据指定索引,于是会自动创建一个0到N-1(N为数据的长度)的整数型索引,取值的时候可以通过索引取    
    
2. 传列表,同时指定索引
pa2 = pd.Series([1,2,3,4,5],index=[1,2,3,4,5])
print(pa2)

pa3 = pd.Series([1,2,3,4,5],index=["1","2","3","4","5"])
print(pa3)

pa4 = pd.Series(np.arange(5),index=list('12345'))
print(pa4)
总结:自定义索引,index是一个索引列表,里面包含的是字符串,依然可以通过默认索引取值。



3.以字典的形式传值
pa5 = pd.Series({'a':1,'b':2})
print(pa5)
执行结果如下:
    a    1
    b    2
    dtype: int64
总结:以字典的key作为索引,(相当于可以指定索引)


4.创建一个值全部为0的数组
pa6 = pd.Series(0,index=[1,2,3,4,5])
print(pa6)
执行结果如下:
	1    0
    2    0
    3    0
    4    0
    5    0
    dtype: int64

总结:Series创建的pandas数据对象,索引与值必须是一一对应的个数

对于Series,其实我们可以认为它是一个长度固定且有序的字典,因为他的索引和数据是按照位置进行匹配的,像我们会使用字典的上下文,就肯定会使用Series

2.Series基础运算使用

  1. 利用ndarry创建Series对象

    nparr = np.arange(5)
    print(nparr)
    pa7 = pd.Series(nparr)# ndarray创建Series对象
    print(pa7)
    执行结果如下:
    	[0 1 2 3 4]
        0    0
        1    1
        2    2
        3    3
        4    4
        dtype: int32
    
  2. 与标量(数字)进行运算

    pa8 = pa7 * 2 # pa7对象中的每一个数据值都*2
    print(pa8)
    执行结果如下:
        0    0
        1    2
        2    4
        3    6
        4    8
        dtype: int32
    
  3. 两个Series对象数据进行运算

    pa9 = pa7 * pa8
    print(pa9)
    执行结果如下:
        0     0
        1     2
        2     8
        3    18
        4    32
        dtype: int32
    
  4. 布尔值过滤----通过numpy的布尔值索引

    print(pa9>2)
    pa10 = pa9[pa9>2]
    print(pa10)
    执行结果如下:
    0    False
    1    False
    2     True
    3     True
    4     True
    dtype: bool
    
    2     8
    3    18
    4    32
    dtype: int32
    
  5. 统计函数

    # 1。mean()---求平均值
    print(pa9.mean())
    
    
    # 2.sum()---求和
    print(pa9.sum())
    
    
    # 3.cumsum()---类似于斐波那契数列
    print(pa9.cumsum())
    
    执行结果如下:
        12.0
        
        60
     
        0     0
        1     2
        2    10
        3    28
        4    60
        dtype: int32
    

3.Series 支持字典的特性

  1. 从字典创建Series:Series(dic)

    dic = {'a':1,'b':2,'c':3,'d':4}
    pa11 = pd.Series(dic)
    
  2. in 运算

    istrue = 'a' in pa11
    print(istrue)
    
    istrue1 = 'e' in pa11
    print(istrue1)
    
    执行结果如下:
        True
        False	
    
  3. 键索引

    value1 = pa11['a']
    print(value1)
    
    value2 = pa11.get('c')
    print(value2)
    # pall['e'] # 取不到会报错(不管是否是get)
    
    # 但是可以给get设置默认值(default)
    value3 = pa11.get('e',default=0)
    print(value3)
    
    # 可以通过键取多个。但是要记得用列表
    value4 = pa11[['a','d']]
    print(value4)
    
  4. 键切片(顾头又顾尾)

    pall['a':'c']
    

4.整数索引

pandas当中的整数索引对象可能会让初次接触它的人很懵逼,接下来通过代码演示
iloc:解释为下标
loc:解释为标签

pa13 = pd.Series(np.arange(10)) #利用ndarray创建Series对象数据
print(pa13)

pa14 = pa13[3:] #相当于列表中的切片取值
print(pa14)

# 以上只是在切片索引取值,那如果我们的需求是,只取其中的某一个值?---我们会发现就出现问题了
value0 = pa13[0] # 在我们原本定义的pa13对象数据,单个取值还是没有问题的
print(value0)


# value1 = pa14[0] # 知道这里我们发信报错了,为什么?



'''
loc属性:以标签做为解释
iloc属性:以下标作为解释,相当于索引

'''
# 当我们直接用pa13[0]取值的时候,实际上是默认以标签作为解释的loc

# 下面我们来用ilog来做实验
value2 = pa13.loc[3]
print(value2) # 没有任何问题的


''' 以下两行代码我们法相报错了。因为切片取得的没有标签为1的值
value3 = pa14.loc[1]
print(value3)
'''
value3 = pa14.iloc[1]
print(value3) # 打印结果,没有任何问题,按索引来取值

5. Series数据对齐

pandas在运算时,会按索引进行对齐然后计算。如果存在不同的索引,则结果的索引是两个操作数索引的并集。

s1 = pd.Series([12,23,34], index=['c','a','d'])
s2 = pd.Series([11,20,10], index=['d','c','a',])

s_sum = s1 + s2
print(s_sum)

执行结果如下:
a    33
c    32
d    45
dtype: int64
# 当两个数据对象索引不同时
s4 = pd.Series([11,20,10,14], index=['d','c','a','b'])
s_sum1 = s1 + s4
print(s_sum1)

# s1 和 s4的索引不一致,所以最终的运行会发现b索引对应的值无法运算,就返回了NaN,一个缺失值

执行结果如下:
a    33.0
b     NaN
c    32.0
d    45.0
dtype: float64
# 将两个Series对象相加时将缺失值设为0
s_sum2 = s1.add(s4,fill_value=0)
print(s_sum2)

执行结果如下:
a    33.0
b    14.0
c    32.0
d    45.0
dtype: float64

DateFrame

DataFrame是一个表格型的数据结构,相当于是一个二维数组,含有一组有序的列。他可以被看做是由Series组成的字典,并且共用一个索引。接下来就一起来见识见识DataFrame数组的厉害吧!!!

1. 创建方式

创建一个DataFrame数组可以有多种方式,其中最为常用的方式就是利用包含等长度列表或Numpy数组的字典来形成DataFrame

pd.DataFrame({'a':pd.Series(np.arange(10)),"b":pd.Series(np.arange(10))})

执行结果如下:
	a	b
0	0	0
1	1	1
2	2	2
3	3	3
4	4	4
5	5	5
6	6	6
7	7	7
8	8	8
9	9	9

data = pd.DataFrame({'one':[1,2,3,4],'two':[4,3,2,1]})
pd.DataFrame(data,columns=['one','two'])

执行结果如下:
	one	two
0	1	4
1	2	3
2	3	2
3	4	1

pd.DataFrame({'one':pd.Series([1,2,3],index=['a','b','c']),'two':pd.Series([1,2,3],index=['b','a','c'])})

执行结果如下:
	one	two
a	1	2
b	2	1
c	3	3

  1. 不指定索引,自动添加

    产生的DataFrame会自动为Series分配所索引,并且列会按照排序的顺序排列 其实也就是字典的key作为列索引

    data1 = pd.DataFrame({'one':[1,2,3,4],'two':[4,3,2,1]})
    print(data1)
    
    执行结果如下:
    	one  two
    0    1    4
    1    2    3
    2    3    2
    3   4    1
    
    
  2. 指定列

    指定列时,列索引一定要是字典中的key,可以不按照顺序

    data2 = pd.DataFrame({'one':[1,2,3,4],'two':[4,3,2,1]})
    data3 = pd.DataFrame(data2,columns=['one','two'])
    print(data3)
    执行结果如下:
    	one  two
    0    1    4
    1    2    3
    2    3    2
    3    4    1
    
    
  3. 指定行索引

    data4 = pd.DataFrame({'one':pd.Series([1,2,3],index=['a','b','c']),'two':pd.Series([1,2,3],index=['b','a','c'])})
    print(data4)
    
    执行结果如下:
    one  two
    a    1    2
    b    2    1
    c    3    3
    
    

    以上创建方法简单了解就可以,因为在实际应用当中更多是读数据,不需要自己手动创建

2. 查看数据

常用属性和方法:

  1. index 获取行索引
  2. columns 获取列索引
  3. T 转置
  4. values 获取值索引
  5. describe 获取快速统计
print(data4) # 有这样一个数组

row_index = data4.index  # 1.获取行索引
print(row_index)


columns_index = data4.columns # 2.获取列索引
print(columns_index)



T_data = data4.T # 3.转置(类似于numpy中的T,将行列转换)
print(T_data)


value_index = data4.values # 4.获取值索引,得到一个数组
print(value_index)


describe_data = data4.describe() # 5.快速统计
print(describe_data)
'''结果
       one  two
count  3.0  3.0   数据统计
mean   2.0  2.0   平均值
std    1.0  1.0   标准差
min    1.0  1.0   最小值
25%    1.5  1.5   四分之一均值
50%    2.0  2.0   二分之一均值
75%    2.5  2.5   四分之三均值
max    3.0  3.0   最大值

'''


3.索引和切片

  • DataFrame有行索引和列索引。
  • DataFrame同样可以通过标签和位置两种方法进行索引和切片。
  1. 方法一:

    两个中括号,无论是先取行还是先取列都可以。

    # tushare是python的一个库,它是用来获取数据的(远程、本地、数据库)
    data5 = ts.get_k_data("000001") # 000001 是中国平安的股票数据
    
    data6 = data5['open'][0] # 先取列再取行
    print(data6)
    执行及如果如下:
    8.737
    
    
    data7 = data5[:10]['open']# 先去行再取列
    data7
    执行结果如下:
    0    8.737
    1    8.747
    2    8.834
    3    8.873
    4    8.873
    5    8.834
    6    8.844
    7    8.805
    8    8.766
    9    8.757
    Name: open, dtype: float64
    
    
  2. 方法二:使用loc/iloc属性

    一个中括号,逗号隔开,先取行再取列。

    data.iloc[0]['date']
    执行结果:'2017-06-06'
    
    
    data8 = data5.loc[:10,"open":'low'] # loc 用标签取
    print(data8)
    执行结果:
    	open  close   high    low
    0   8.737  8.766  8.786  8.718
    1   8.747  8.854  8.873  8.737
    2   8.834  8.854  8.873  8.805
    3   8.873  8.873  8.941  8.844
    4   8.873  8.834  8.912  8.825
    5   8.834  8.844  8.863  8.776
    6   8.844  8.805  8.854  8.766
    7   8.805  8.766  8.805  8.757
    8   8.766  8.747  8.805  8.737
    9   8.757  8.854  8.873  8.747
    10  8.844  8.844  8.883  8.815
    
    
    data9 = data5.iloc[:10,1:5]  # iloc 用下表索引取
    print(data9)
    执行结果:
        open  close   high    low
    0  8.737  8.766  8.786  8.718
    1  8.747  8.854  8.873  8.737
    2  8.834  8.854  8.873  8.805
    3  8.873  8.873  8.941  8.844
    4  8.873  8.834  8.912  8.825
    5  8.834  8.844  8.863  8.776
    6  8.844  8.805  8.854  8.766
    7  8.805  8.766  8.805  8.757
    8  8.766  8.747  8.805  8.737
    9  8.757  8.854  8.873  8.747
    
    

时间对象处理

处理时间对象可能是我们在进行数据分析的过程当中最常见的,我们会遇到各种格式的时间序列,也需要处理各种格式的时间序列,但是一定不能对这些数据懵逼,我们需要找到最合适的招式来处理这些时间。接下来就一起来看吧!!!

1. 时间序列类型

  • 时间戳:特定时刻
  • 固定时期:如2020年1月
  • 时间间隔:起始时间-结束时间

2. python库:datetime

  • date、datetime、timedelta
# datetime.date()  # date对象
today = datetime.date.today()  # 获取当天日期,返回date对象
print(today)

t1 = datetime.date(2019,4,18) # 设置时间格式为datetime.date
print(t1)




# datetime.datetime()  # datetime对象
now = datetime.datetime.now()  # 获取当天日期,返回datetime对象
print(now)
t2 = datetime.datetime(2019,4,18) # 设置时间格式为datetime.datetime
print(t2)



# datetime.timedelta()  # 时间差
today = datetime.datetime.today()
print(today)
yestoday = today - datetime.timedelta(1)  # 以时间做运算
print(yestoday)

  • strftime()---时间格式转换为字符串
# 将时间格式转换为字符串
print(yestoday)
s_yestoday = yestoday.strftime("%Y-%m-%d")
print(s_yestoday)

  • strptime
# 将日期字符串转成datetime时间格式,第二个参数由时间格式决定
date_time = datetime.datetime.strptime('2019-04-18','%Y-%m-%d')
print(date_time)

3.dateutile包

  • deteutil .parser.parse()

    import dateutil
    
    # 将字符串格式的日期转换为datetime对象
    date = '2019 Jan 2nd'
    t3 = dateutil.parser.parse(date)
    print(t3)
    
    

4. to_datetime 处理多个时间对象

# 转换单个时间数据是返回Timestamp对象,转换多个时间数据返回DatetimeIndex对象
date1 = datetime.datetime(2019, 4, 18, 12, 24, 30)
date2 = '2019-04-18'

# Timestamp对象
t4 = pd.to_datetime(date1)
print(t4)

t5 = pd.to_datetime(date2)
print(t5)


# DatetimeIndex对象
t6 = pd.to_datetime([date1,date2])
print(t6)

  • 将索引设置为时间序列

    ind = pd.to_datetime(['2018-03-01','2019 Feb 3','08/12-/2019'])
    sr = pd.Series([1,2,3],index=ind)
    print(sr)
    
    

5. 产生事件对象数组:date_range

  • start 开始时间
  • end 结束时间
  • periods 时间长度
  • freq 时间频率,默认为‘D’,可选H(our),W(eek),B(usiness),S(emi-)M(onth),(min)T(es)、S(econd)、A(year)·····
pd.date_range("2019-1-1","2019-2-2",freq="B")

执行结果:
DatetimeIndex(['2019-01-01', '2019-01-02', '2019-01-03', '2019-01-04',
               '2019-01-07', '2019-01-08', '2019-01-09', '2019-01-10',
               '2019-01-11', '2019-01-14', '2019-01-15', '2019-01-16',
               '2019-01-17', '2019-01-18', '2019-01-21', '2019-01-22',
               '2019-01-23', '2019-01-24', '2019-01-25', '2019-01-28',
               '2019-01-29', '2019-01-30', '2019-01-31', '2019-02-01'],
              dtype='datetime64[ns]', freq='B')

6. 时间序列

时间序列就是以时间对象为索引的Series或dataFrame。

datetime对象作为索引的是存储再Datetimeindex对象中的

# 转换时间索引
dt = pd.date_range("2019-01-01","2019-01-04")
print(dt)
执行结果:
DatetimeIndex(['2019-01-01', '2019-01-02', '2019-01-03', '2019-01-04',
              dtype='datetime64[ns]', freq='D')




# 生成一个带有时间数据的DataFrame数组
a = pd.DataFrame({"num":pd.Series(np.random.randint(-100,100) for _ in range(5)),"date":dt})
print(a)
执行结果:
 	num       date
0   -12 2019-01-01
1    25 2019-01-02
2     2 2019-01-03
3    61 2019-01-04
4   -27 2019-01-05



# # 通过index修改行索引
a.index = pd.to_datetime(a["date"])
print(a)
执行结果:
 			num       date
date                      
2019-01-01  -12 2019-01-01
2019-01-02   25 2019-01-02
2019-01-03    2 2019-01-03
2019-01-04   61 2019-01-04

特殊功能:

  • 传入”年“或”月“作为切片方式
  • 传入日期范围作为切片方式
  • 丰富的函数支持:resample(),strftime()
a.resample("3D").mean() # 计算每三天的均值
a.resample("3D").sum() # 计算每三天的和

注意:时间序列的处理再数据分析当中非常重要,但是有时候时间的格式不一致有会让人非常烦躁,只要把以上秘籍全部都学会,就可以把时间序列制服的服服帖帖

posted @ 2020-02-16 14:46  chanyuli  阅读(393)  评论(0编辑  收藏  举报