数据分析之pandas

一.Pandas 

 1.1简介

pandas是一个强大的Python数据分析的工具包,它是基于Numpy构建的,相当于Numpy的升级版本(自己瞎说的)正因pandas的出现,让Python语言也成为使用最广泛而且强大的数据分析环境之一

   1.2 pandas 的主要功能:

  

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

  安装:pip install pandas  (我们已经安装Anaconda 直接导入就行乐)

  引用方法:

    import pandas as pd (约定俗成)

 2.Series

  Series是一种类似于一维数组的对象,由一组数据和一组与之相关的数据标签(索引)组成。

  (1)创建方法

    

   Pandas的相关使用
import pandas as pd
# 1.第一种 不指定索引  自动指定0起始缩引
l1 = [6,9,2,3,4,5,6]
pd.Series(l1)
0    6
1    9
2    2
3    3
4    4
5    5
6    6
dtype: int64
?
# 将数组索引以及数组的值打印出来,索引在左,值在右,
# 由于没有为数据指定索引,于是会自动创建一个0到N-1(N为数据的长度)的整数型索引,
# 取值的时候可以通过索引取
?
‘a‘,‘b‘,‘c‘
# 第二种 指定索引 左索引 右对应的值
l2 = [2,3,4,6,7]
pd.Series(l2,index=[‘a‘,‘b‘,‘c‘,‘b‘,‘e‘])
a    2
b    3
c    4
b    6
e    7
dtype: int64
的数组
# 第三种  创建一个值都是0的数组
pd.Series(0,index=[‘a‘,‘b‘,‘c‘])
a    0
b    0
c    0
dtype: int64
# 2 。缺失值的使用和应用场景
# 对于Series,其实我们可以认为它是一个长度固定且有序的字典,
# 因为它的索引和数据是按位置进行匹配的,
# 像我们会使用字典的上下文,就肯定也会使用Series
    
Series
# (1)dropna()  # 过滤值为NaN的行
#  (2)fill() # 田聪缺失值
#  (3)isnull() #  返回布尔值数组,缺失值对应为True
#   (4)notnull # 返回布尔值数组,缺失值对应为False
tu = {"kk":18,"cc":19,"yy":20,"tt":21}
# 将字典通过panda
# 第一步 ,创建一个字典,通过Series方式创建一个Series 对像
stu = {"kk":18,"cc":19,"yy":20,"tt":21}
# 将字典通过pandas的Series 转成数组对象
obj = pd.Series(stu)
obj
kk    18
cc    19
yy    20
tt    21
dtype: int64
我们自己传入一个么有的key 则回出现 一个uu:NaN
# 第二步 定义一个索引变量
a = {"kk","cc","yy","uu"}   # 我们自己传入一个么有的key 则回出现 一个uu:NaN
# 第三步 将a 传入作为索引
stu1 =pd.Series(stu,index=a)
stu1
cc    19.0
yy    20.0
uu     NaN
kk    18.0
dtype: float64# 我们自己传入一个么有的key 则回出现 一个uu:NaN 返回的是 一个确实值
?
# 综合上面的代码我们可以 通过isnull() 进行判断是否有缺失值
# 1.isnull()
stu1.isnull()  3 缺失值返回True
cc    False
yy    False
uu     True
kk    False
dtype: bool# 2  notnull()
stu1.notnull()  #   # >>>  # 缺失值返回Fasle 不是缺失值返回True
cc     True
yy     True
uu    False
kk     True
dtype: bool
方法:直接
# 3 方法:直接过滤缺失值  》》》 布尔类型索引
?
stu1[stu1.notnull()]
cc    19.0
yy    20.0
kk    18.0
dtype: float64

(2)Series 的特性

  a.从ndarray类创建 Series:Series(arr)
    

  与标量(数字):str*2
  两个Seriesy运算
  通用函数:np.ads(sr)
  布尔值过滤:Sr[sr>0]
  统计函数:mean(), sum(), cusum()

  b.支持字典的特性:

  从字典创建Series:Series(dic),
  In运算:‘a‘in sr、for x in sr
  键索引:sr[‘a‘],sr[[‘a‘,‘b‘,‘d‘]]
  键切片:sr[‘a‘:‘c‘]
  其他函数:get(‘a‘,default=0)等

  整数索引

  pandas 当中的整数索引对象 代码演示:

  

obj1 = pd.Series(np.arange(10)   # 0,1,2,3,4,5,6,7,8,9
obj2 = obj1[3:].copy()
obj2

# 代码演示
obj1 = pd.Series(np.arange(10)   # 0,1,2,3,4,5,6,7,8,9
obj2 = obj1[3:].copy()
obj2
?
3    3
4    4
5    5
6    6
7    7
8    8
9    9
dtype: int32
重
# obj2[1]  obj2[3]取标签是可以i的  不要自己想当然  验证
# 无法取出obj2的值
# 解决方案
# (1)loc属性 》》》以标签解释
#  (2)iloc属性 》》》 以下标解释 
obj2.loc[4]  # 这个就是标签 和obj[3] 是一样的取值方法
# obj2.iloc[0] 重新排列的数据索引从0开始的 [0] 可以取值3 [1] 4
4

Series 数据对齐

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

实列:

s1 = pd.Series([11,22,33],index=[‘a‘,‘b ‘,‘c‘])
# Series数据对齐
s1 = pd.Series([11,22,33],index=[‘a‘,‘b ‘,‘c‘])
s2 = pd.Series([44.,55,66],index=[‘d‘,‘c‘,‘a‘])
s1+s2
a     77.0
b      NaN
c     88.0
d      NaN
dtype: float64
ue=0)
#  s1 和s2 的索引不一致, 所以最终的运行通过index b和d没有对应的就会 值就会返回NaN 是一个确实值
# 解决方案 我们将两个Series 对象相加sh8将缺失值设置为 0
s1 = pd.Series([11,22,33],index=[‘a‘,‘b‘,‘c‘])
s3 = pd.Series([100,200,300,500],index=[‘c‘,‘a‘,‘b‘,‘e‘])
s1.add(s3,fill_value=0)
a    211.0
b    322.0
c    133.0
e    500.0
dtype: float64

# 将e 的对应到s1缺失值设置为0 =500+0 结果500
# 灵活算法add,sub,div,mul

 3.DataFrame

  DataFrame是一种表格的数据结构,相当于一个二维数组, 含有一组有序的列,

  可以看做是由Series组成的字典,并且共用一个索引

创建方法:

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

# 第一种
# 第一种
pd.DataFrame({"one":[1,2,3,4],"two":[6,7,8,9]})
# DataFrame 会自动分配索引,并且按按照排列的顺序排列

                      one    two
                  0    1    6
                   1    2    7
                  2    3    8
                  3    4    9
# 指定列 可以通过columns 参数指定顺序排列data = pd.DataFrame({"one":[1,2,3,4],"two":[6,7,8,9]})pd.DataFrame(data,columns=["two","one"])


 
two
one



0
6
1




1
7
2




2
8
3




3
9
4






 # 第二种

# 第二种
pd.DataFrame({"n1":pd.Series([1,2,3],index=[‘a‘,‘b‘,‘c‘]),‘n2‘:pd.Series([9,7,6],index=[‘c‘,‘a‘,‘b‘])})


 
n1
n2



a
1
7


b
2
6


c
3
9




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

index 获取行索引
columns 获取列索引
T 转置
columns 获取列索引
values 获取值索引
describe 获取快速统计

   结果

df.index  # 获取索引
Index([‘a‘, ‘b‘, ‘c‘], dtype=‘object‘)
df.columns
df.columns
Index([‘n1‘, ‘n2‘], dtype=‘object‘)
df.T
?
a    b    c
n1    1    2    3
n2    7    6    9
s
df.values
?
array([[1, 7],
       [2, 6],
       [3, 9]], dtype=int64)
df.describe()
)
n1    n2
count    3.0    3.000000
mean    2.0    7.333333
std    1.0    1.527525
min    1.0    6.000000
25%    1.5    6.500000
50%    2.0    7.000000
75%    2.5    8.000000
max    3.0    9.000000

切片和索引

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

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

   # 获取数据源

pd.read_csv(‘文件路径‘)

# 获取数据源
f = pd.read_csv(‘./douban_movie.csv‘)
f

f.head()   # 读取前面四条数据
f.tail()  # 读取后面四条数据
f.to_csv(‘./aaa.csv‘)  # 重保存一分到我们的当前文件

f.to_csv(‘./aaa.csv‘,index=False)  # 重保存一分到我们的当前文件  index=False 去除保存的索引,

用因为他会默认加索引 只需要一个index 即可

作业:

2. pd.read_html
pandas 计算历年nba 球队获取总冠军的次数

import pandas as pd

res=pd.read_html(‘https://baike.baidu.com/item/NBA%E6%80%BB%E5%86%A0%E5%86%9B/2173192?fr=aladdin‘)
res

(1)获取的数据是两张列表

表一

[       0          1          2    3        4         5
    年份       比赛日期         冠军  总比分       亚军      FMVP
 4.16-4.22      费城勇士队  4-1   芝加哥牡鹿队         无
 4.10-4.21    巴尔的摩子弹队  4-2    费城勇士队         无
  4.4-4.13  明尼阿波利斯湖人队  4-2   华盛顿国会队         无
  4.8-4.23  明尼阿波利斯湖人队  4-2  塞拉库斯民族队         无
 ..   ...        ...        ...  ...      ...       ...
  6.5-6.17      金州勇士队  4-2  克里夫兰骑士队  安德烈·伊戈达拉
  6.3-6.20    克里夫兰骑士队  4-3    金州勇士队   勒布朗·詹姆斯
  6.2-6.13      金州勇士队  4-1  克利夫兰骑士队    凯文·杜兰特
   6.1-6.9      金州勇士队  4-0  克利夫兰骑士队    凯文·杜兰特
 5.31-6.14     多伦多猛龙队  4-2    金州勇士队    科怀·伦纳德]

表二

[74 rows x 6 columns],        0    1                  2     3   0     联盟   赛区                 球队  夺冠次数   
  东部联盟  大西洋           波士顿凯尔特人队    17   
  西部联盟  太平洋             洛杉矶湖人队    16   
  西部联盟  太平洋          金州勇士队 [1]     6   
  东部联盟   中部             芝加哥公牛队     6   
  西部联盟   西南           圣安东尼奥马刺队     5   
  东部联盟  大西洋             费城76人队     3   
  东部联盟   中部             底特律活塞队     3   
  东部联盟   东南             迈阿密热火队     3   
  东部联盟  大西洋             纽约尼克斯队     2   
 西部联盟   西南             休斯敦火箭队     2   
 西部联盟  太平洋           萨克拉门托国王队     1   
 东部联盟   东南            亚特兰大老鹰队     1   
 东部联盟   中部            密尔沃基雄鹿队     1   
 西部联盟   西北            波特兰开拓者队     1   
 东部联盟   东南             华盛顿奇才队     1   
 西部联盟   西北  俄克拉荷马城雷霆队(西雅图超音速)     1   
 西部联盟   西南             达拉斯小牛队     1   
 东部联盟   中部            克里夫兰骑士队     1   
 东部联盟  大西洋             多伦多猛龙队     1   
 东部联盟  大西洋            布鲁克林篮网队     0   
 东部联盟   中部           印第安纳步行者队     0   
 东部联盟   东南             夏洛特黄蜂队     0   
 东部联盟   东南             奥兰多魔术队     0   
 西部联盟  太平洋             洛杉矶快船队     0   
 西部联盟  太平洋            菲尼克斯太阳队     0   
 西部联盟   西北              丹佛掘金队     0   
 西部联盟   西北           明尼苏达森林狼队     0   
 西部联盟   西北              犹他爵士队     0   
 西部联盟   西南             孟菲斯灰熊队     0   
 西部联盟   西南            新奥尔良鹈鹕队     0   
  已撤销  已撤销             巴尔的摩子弹     1   
 
                                               夺冠年份  
  1957、1959-1966、1968-1969、1974、 1976、1981、1984、...  
  1949-1950、1952-1954、1972、1980、1982、 1985、1987-...  
                      1947、1956、1975、2015、2017-2018  
                                1991-1993、1996-1998  
                           1999、2003、2005、2007、2014  
                                     1955、1967、1983  
                                     1989-1990、2004  
                                     2006、2012、2013  
                                          1970、1973  
                                         1994-1995  
                                              1951  
                                              1958  
                                              1971  
                                              1977  
                                              1978  
                                              1979  
                                              2011  
                                              2016  
                                              2019  
                                               NaN  
                                               NaN  
                                               NaN  
                                               NaN  
                                               NaN  
                                               NaN  
                                               NaN  
                                               NaN  
                                               NaN  
                                               NaN  
                                               NaN  
                                  1948(该队并非现奇才队前身)  ]

 (2)我们只要第一张表

 res1 = res[0]  # 获取第一张冠军的表

数据分析之pandas

(3)  将索引为0的这一条数据 赋值给 列名"

 res1.columns = res1.iloc[0]
 res1  #  将索引为0的这一条数据  赋值给 列名"
将索引为0的这一条数据  赋值给 列名"

数据分析之pandas

(4)# 统计个数 res1.groupby(‘冠军‘).size() 再 进行排列asc=True 默认识升序 我们要降序

# res1.groupby(‘冠军‘).size().sort_values(ascending=False)
# res1.groupby(‘冠军‘).size().sort_values(desc)  注意desc 在pandas 中用asc=False 而且要全写不能简写
res1.groupby(‘冠军‘).size().sort_values(ascending=False)

数据分析之pandas

   

 

 4.时间对象处理

  

时间序列类型

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

Python库:datatime

  • date、time、datetime、timedelta
  • dt.strftime()
  • strptime()

灵活处理时间对象:dateutil包

  • dateutil.parser.parse()
import dateutil
dateutil.parser.parse("2019 Jan 2nd")  # 这中间的时间格式一定要是英文格式

运行结果:
datetime.datetime(2019, 1, 2, 0, 0)

成组处理时间对象:pandas

  • pd.to_datetime([‘2018-01-01‘, ‘2019-02-02‘])
pd.to_datetime([‘2018-03-01‘,‘2019 Feb 3‘,‘08/12-/019‘])

运行结果:
DatetimeIndex([‘2018-03-01‘, ‘2019-02-03‘, ‘2019-08-12‘], dtype=‘datetime64[ns]‘, freq=None)  # 产生一个DatetimeIndex对象

# 转换时间索引
ind = pd.to_datetime([‘2018-03-01‘,‘2019 Feb 3‘,‘08/12-/019‘])
sr = pd.Series([1,2,3],index=ind)
sr
运行结果:
2018-03-01    1
2019-02-03    2
2019-08-12    3
dtype: int64
通过以上方式就可以将索引转换为时间
补充:
pd.to_datetime([‘2018-03-01‘,‘2019 Feb 3‘,‘08/12-/019‘]).to_pydatetime()
运行结果:
array([datetime.datetime(2018, 3, 1, 0, 0),
       datetime.datetime(2019, 2, 3, 0, 0),
       datetime.datetime(2019, 8, 12, 0, 0)], dtype=object)
# 通过to_pydatetime()方法将其转换为array数组

产生时间对象数组:data_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")
运行结果:
DatetimeIndex([‘2019-01-01‘, ‘2019-01-02‘, ‘2019-01-03‘, ‘2019-01-04‘,
               ‘2019-01-05‘, ‘2019-01-06‘, ‘2019-01-07‘, ‘2019-01-08‘,
               ‘2019-01-09‘, ‘2019-01-10‘, ‘2019-01-11‘, ‘2019-01-12‘,
               ‘2019-01-13‘, ‘2019-01-14‘, ‘2019-01-15‘, ‘2019-01-16‘,
               ‘2019-01-17‘, ‘2019-01-18‘, ‘2019-01-19‘, ‘2019-01-20‘,
               ‘2019-01-21‘, ‘2019-01-22‘, ‘2019-01-23‘, ‘2019-01-24‘,
               ‘2019-01-25‘, ‘2019-01-26‘, ‘2019-01-27‘, ‘2019-01-28‘,
               ‘2019-01-29‘, ‘2019-01-30‘, ‘2019-01-31‘, ‘2019-02-01‘,
               ‘2019-02-02‘],
              dtype=‘datetime64[ns]‘, freq=‘D‘)

时间序列

时间序列就是以时间对象为索引的Series或DataFrame。datetime对象作为索引时是存储在DatetimeIndex对象中的。

# 转换时间索引

dt = pd.date_range("2019-01-01","2019-02-02")
a = pd.DataFrame({"num":pd.Series(random.randint(-100,100) for _ in range(30)),"date":dt})

# 先生成一个带有时间数据的DataFrame数组

a.index = pd.to_datetime(a["date"])
# 再通过index修改索引

特殊功能:

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

    5.数据分组和聚合方法

  上面的案列做的简单介绍

   6.其他常用方法

pandas常用方法(适用Series和DataFrame)

  • mean(axis=0,skipna=False)
  • sum(axis=1)
  • sort_index(axis, …, ascending) # 按行或列索引排序
  • sort_values(by, axis, ascending) # 按值排序
  • apply(func, axis=0) # 将自定义函数应用在各行或者各列上,func可返回标量或者Series
  • applymap(func) # 将函数应用在DataFrame各个元素上
  • map(func) # 将函数应用在Series各个元素上