<返回更多

Python-Pandas模块Series

2020-07-19    
加入收藏

1. 什么是Series?

Series是一种类似于一维数组的对象,与一维数组对象不同的是Series带有标签(索引),通俗来说就是一维带标签(索引)的一维数组。如下图所示:

Python-Pandas模块Series

带有索引的一维数组

2. 如何创建Series?

Series是一维带标签(索引)的一维数组,对于Series最关键的也就是索引index和与之对应的value值

一般格式 (这里的data就是value值的集合):
s = pd.Series( data , index )

data几种常见的取值类型:

  1. 标量值、list列表;
  2. ndarray对象;
  3. dict字典;

index取值规范:

  1. 索引值必须是可hashable的(如果一个对象是可散列的,那么在这个对象的生命周期中,他的散列值是不会变的(它需要实现__hash__()方法)),并且索引index的长度必须和value值的长度一致,如果不一致会抛出异常(这点需要格外的注意);
  2. 如果不设置索引,默认索引是从0到n-1的序列值[其中n为data值的长度];
  3. 如果data的类型为dict字典类型,对应的字典中的key值就是对应series对象中的index值;
  4. 相同的索引值也是可以的;

下面依照着data的几种常见的类型来分别介绍,中间会穿插着index的取值规范问题:

2.1 data为标量值、list列表

#data:标量值1
#index:不指定(默认索引)
import pandas as pd
s = pd.Series(1)
print(s)

result:
0    1
dtype: int64
#data:list列表
#index:通过list列表指定,其中data和index长度一致
import pandas as pd
s = pd.Series([1,2,3,4,5],index = ["a","a","c","d","e"])
print(s)

result:
a    1
a    2
c    3
d    4
e    5
dtype: int64

注意:

  • 当创建Series对象的时候指定index的时候,index元素个数(此处的index为一个list列表)要和data中元素个数相等;
  • 使用相同的索引值"a",程序并没有发生异常,索引值可以是相同的;

2.2 data为ndarray对象

import numpy as np
import pandas as pd

data = np.arange(5)
#使用list作为index索引
index2 = ["a","b","c","d","e"]
#使用ndarray数组作为index索引
index3 = np.array(["a","b","c","d","e"])

s = pd.Series(data)
s2 = pd.Series(data,index2)
s3 = pd.Series(data,index3)

print(s)
print("-"*6)
print(s2)
print("-"*6)
print(s3)

result:
0    0
1    1
2    2
3    3
4    4
dtype: int32
------
a    0
b    1
c    2
d    3
e    4
dtype: int32
------
a    0
b    1
c    2
d    3
e    4
dtype: int32

注意:

  • 此时的data是ndarray数组类型,而index分别指定了无参数的默认index索引、指定list列表以及指定ndarray数组类型的index。

2.3 data为dict字典

import pandas as pd

d = {"a":0,"b":1,"c":2}
s = pd.Series(d)
print(s)

result:
a    0
b    1
c    2
dtype: int64

这里由于将data位置的参数传入字典,将字典的键作为了Series对象的index,所以如果再次指定index的时候会出现一些新的情况:

  1. 指定的index中不包含字典中的键值;
  2. 指定的index中包含部分字典中的键值;
  3. 指定的index中包含全部的字典中键值;

下面就使用代码简单的介绍一下这三种情况。

  • 指定的index中不包含字典中的键值
import pandas as pd
d = {"a":0,"b":1,"c":2}
s = pd.Series(d,index = ["d","e"])
print(s)

result:
d   NaN
e   NaN
dtype: float64
  • 指定的index中包含部分字典中的键值
import pandas as pd
d = {"a":0,"b":1,"c":2}
s = pd.Series(d,index = ["a","d"])
print(s)

result:
a    0.0
d    NaN
dtype: float64
  • 指定的index中包含全部的字典中键值
import pandas as pd
d = {"a":0,"b":1,"c":2}
s = pd.Series(d,index = ["a","b","c"])
print(s)

result:
a    0
b    1
c    2
dtype: int64

总结:

我们知道创建Series对象的一般格式,包含两个参数data和index索引。我们使用Python字典作为创建Series的data,同时我们知道当将字典作为创建Series对象的data的话,Python字典中的key可以作为Series的index,但是此时我们仍然可以继续指定index,通过上面的三种情况的描述,可以得出结论,使用字典创建Series,同时指定index的话,此时的index起到一个筛选的作用,最终的输出结果就是指定的index,如果指定的index在字典中的key中,则将对应的值关联到指定的index中;如果指定的index不在字典中的key中,则将NaN关联到指定index中。由于Python中字典中的key不能够重复,所以虽然Series允许使用有重复的index值,但是如果使用字典创建Series的时候肯定不会有相同的index值。

3. Series的属性

此处介绍Series属性包括两个方面(因为此处介绍的是Series的属性不是Series的方法,所以不要在后面加小括号):

  1. 获取Series的index索引和value值,顺便介绍统计index和value相同类别的个数的方法;
  2. 获取Series的名称以及index的名称;
#实验所用到的Series对象
import pandas as pd
s = pd.Series([1,2,3],index = ["a","b","a"])
print(s)

3.1 获取index索引和value值,并统计index和value相同类别的个数

下面将index和value分开来介绍:

#获取Series的索引
print(s.index)

result:
Index(['a', 'b', 'a'], dtype='object')

此时返回的索引是一个迭代器对象,这个对象还可能会有其他的属性。如果我们想要获取其中的具体值的话,可以使用for循环进行遍历,还可以使用下面这些简单的属性将迭代转换为ndarray数组或者是list列表:

print(s.index.values)
print(type(s.index.values))
print("-"*6)
print(list(s.index.values))
print(type(list(s.index.values)))

result:
['a' 'b' 'a']
<class 'numpy.ndarray'>
------
['a', 'b', 'a']
<class 'list'>

如果我们想要统计Series中索引相同索引的个数,可以使用下面的方法(注意此时是方法不在是属性了):

print(s.index.value_counts())

result:
a    2
b    1
dtype: int64

values其实和index类似,下面简单的介绍一下:

print(s.values)
print(type(s.values))

result:
[1 2 3]
<class 'numpy.ndarray'>

与获取index不同的是,使用s.values返回的就是包含值的ndarray数组类型。下面统计相同value值的个数,同样这个也是一个方法,这个方法还是很常用的:

print(s.value_counts())

result:
3    1
2    1
1    1
dtype: int64

3.2 获取Series的名称以及index的名称

Series有本身以及index和value,除了value没有名称外,Series本身和index都可以指定名称,如果不指定的话默认为None。

s.name = "my Series"
s.index.name = "my index"
print(s)

result:
my index
a    1
b    2
a    3
Name: my Series, dtype: int64

4. Series的索引获取指定值

Series简单来说就是带有索引的一维数组,我们很自然的可以通过索引来获取对应的value值,我们有三种方式进行索引:

  1. 位置索引。通过0 ~ n-1[n为Series中索引个数]进行索引;
  2. 名称索引。通过传入指定的index名称来进行索引;
    1. 获取单个索引值;
    2. 获取多个索引值;
  3. 点索引。通过".index名称"的形式进行索引;

下面来分别介绍这三种索引方式以及需要注意的地方。

import pandas as pd

s = pd.Series([1,2,3,4],index = ["a","b","c","d"])
print(s)

4.1 位置索引

# 位置索引
print(s[0])
print(s[-1])
print(s[2])

result:
1
4
3

此处的位置索引类似python中的list列表,不仅能够正向索引[从0开始]而且还能够反向索引[从-1开始反向索引]。

4.2 名称索引

# index名称索引
#获取单个索引值
print(s["a"])
print("*"*6)
#获取多个索引值
print(s[["a","b","c"]])

result:
1
******
a    1
b    2
c    3
dtype: int64

使用名称索引不仅可以索引单个value值,也可以索引多个value值。平时用的最多的就是位置索引和名称索引,说一说使用他们的时候需要注意的地方:

  • 我们知道Series的index索引可以是任意类型,如果index为整数类型,那么位置索引就会失效。
import pandas as pd
s = pd.Series(["a","b","c","d"],index = [1,3,4,5])

# 此处使用位置索引会抛出异常KeyError
# print(s[-1])
# print(s[2])

#此处得到的结果是名称索引
print(s[3])

result:
b
  • 由于Series的index是可以重复的,对于位置索引来说无论index是否重复都与索引没有关系,但是如果使用名称索引的话,索引出来的是结果是一个具有相同index的Series对象。
import pandas as pd
s = pd.Series(["a","b","c","d"],index = [1,1,4,5])

# 此处使用的是名称索引
print(s[1])
result:
1    a
1    b
dtype: object

4.3 点索引

平时使用名称索引以及位置索引足够使用。点索引使用有很多局限性:

  1. 点索引只使用于Series的index类型为非数值类型才可以使用;
  2. 如果Series中的index中有一些索引名称与Python的一些关键字或者一些函数名重名的话,会导致无法获取Series的值;
import pandas as pd

# 此时的index为数值类型
s = pd.Series(["a","b","c","d"],index = [1,2,3,4])

# 会抛出语法错误的异常SyntaxError
# print(s.2)
import pandas as pd

# 此时的index为数值类型
s = pd.Series([1,2,3,4],index = ["a","b","c","def"])

# 通过点索引获取value值
print(s.a)
# 会抛出语法错误的异常SyntaxError
# print(s.def)

result:
1

5. Series的切片slice

通过Series的切片来获取连续的多个索引对应的值,Series的切片有两种方式:

  1. 使用位置切片,类似s[start_index : end_index],熟悉python都知道这种切片方式,需要注意的这种方式切片同样是包左不包右;
  2. 使用名称切片,类似s [start_index_name , end_index_name],这种方式和上面使用位置切片的最大区别就是名称切片,即包左又包右
import pandas as pd

s = pd.Series([1,2,3,4],index = ["a","b","c","d"])
print(s)

result:
a    1
b    2
c    3
d    4
dtype: int64

5.1 位置切片

# 使用位置切片
print(s[0:2])

result:
a    1
b    2
dtype: int64

5.2 名称切片

# 使用名称切片
print(s["b":"d"])

result:
b    2
c    3
d    4
dtype: int64

注意:

在上面的索引方式,我们知道了位置索引和名称索引在index为数值类型时候的不同,当index为数值类型的时候,使用位置索引会抛出keyerror的异常,也就是说当index为数值类型的时候,索引使用的是名称索引。但是在切片的时候,有很大的不同,如果index为数值类型的时候,切片使用的是位置切片。总的来说,当index为数值类型的时候:

  1. 进行索引的时候,相当于使用的是名称索引;
  2. 进行切片的时候,相当于使用的是位置切片;

6. Series的增删改查

6.1 添加Series的值(增)

为Series添加新的值的方式有两种:

  1. 使用series.Append(pd.Series(data,index))的方式添加,这种方式会返回一个新的Series对象,这种方式最大的特点就是可以添加多个Series值;
  2. 使用series["new_index"] = value的方式添加,这种方式会直接在原来的Series上进行修改,并且这种方式每次只能够添加一个Series值;
import pandas as pd

s = pd.Series(1,index =["a"])
print(s)
print("*"*6)
# 使用append方式添加多个Series值
# 此处将返回的值赋值给了原来的Series,因为使用append添加的话返回的是新的Series对象
s = s.append(pd.Series([2,3],index = ["b","c"]))
print(s)
print("*"*6)

# 使用s[new_index] = value方式添加
s["d"] = 4
print(s)

result:
a    1
dtype: int64
******
a    1
b    2
c    3
dtype: int64
******
a    1
b    2
c    3
d    4
dtype: int64

6.2 删除series的值(删)

删除直接使用del关键字删除即可。

import pandas as pd
 
s = pd.Series([1,2,3,4],index = ["a","b","c","d"])
print(s)
print("*"*6)
del s["b"]
print(s)

result:
a    1
b    2
c    3
d    4
dtype: int64
******
a    1
c    3
d    4
dtype: int64

6.3 通过索引修改Series的值(改)

其实此时介绍的修改Series的值和在4中介绍的一致,只不过将4中介绍的获取到的Series值进行重新的赋值即是修改对应Series的值,因此此处也有三种方式:

  1. 通过位置索引修改value值;
  2. 通过名称索引修改value值;
  3. 通过点索引修改value值;

此处因为类似,所以只选择一个进行实验:

import pandas as pd

s = pd.Series([1,2,3,4],index = ["a","b","c","d"])

s["a"] = 100
print(s)

result:
a    100
b      2
c      3
d      4
dtype: int64

6.4 判断索引是否在Series中(查)

判断index是否在Series中很简单,其实和python中查看元素是否在list列表中的方法是一样的。

import pandas as pd
 
s = pd.Series([1,2,3,4],index = ["a","b","c","d"])
print("a" in s)
print("q" in s)

result:
True
False

7. 过滤Series的值

我们可以通过布尔选择器,也就是条件筛选来过滤一些特定的值,从而仅仅获取满足条件的值。过滤Series的值的方式分为两种:

  1. 单条件筛选;
  2. 多条件筛选;
import pandas as pd
 
s = pd.Series([1,2,3,4],index = ["a","b","c","d"])

7.1 单条件筛选

print("-"*5 + "布尔选择器" + "-"*5)
print(s < 3)
print("-"*5 + "单条件查询" + "-"*5)
print(s[s<3])

result:
-----布尔选择器-----
a     True
b     True
c    False
d    False
dtype: bool
-----单条件查询-----
a    1
b    2
dtype: int64

7.2 多条件查询

print("-"*5 + "多条件查询" + "-"*5)
print(s[(s > 2) & (s < 4) ])

result:
-----多条件查询-----
c    3
dtype: int64

注意:

  1. 多条件查询中的and以及or必须使用对应的符号来表示,and用&,or用|来表示;
  2. 使用多条件的时候,为了避免出错,在每个条件上最好加上括号;

8. Series缺失值的处理

  1. 判断Value值是否为缺失值,isnull()判断series中的缺失值以及s.notnull()判断series中的非缺失值;
  2. 删除缺失值
    1. 使用dropna();
    2. 使用isnull()以及notnull();
  3. 填充缺失值
    1. 使用fillna;
      1. 使用指定值填充缺失值;
      2. 使用插值填充缺失值;
        1. 向前填充ffill;
        2. 向后填充bfill;
# 创建一个带缺失值的Series
import pandas as pd

s = pd.Series([1,2,None,4])
print(s)

result:
0    1.0
1    2.0
2    NaN
3    4.0
dtype: float64

8.1 判断value值是否为缺失值

有两种方式判断:

  1. s.isnull()判断s中的缺失值;
  2. s.notnull()判断s中的非缺失值;
# 缺失值的地方为True
print("-"*5 + "使用s.isnull判断" + "-"*5)
print(s.isnull())
#缺失值的地方为False
print("-"*5 + "使用s.notnull判断" + "-"*5)
print(s.notnull())

result:
-----使用s.isnull判断-----
0    False
1    False
2     True
3    False
dtype: bool
-----使用s.notnull判断-----
0     True
1     True
2    False
3     True
dtype: bool

8.2 删除缺失值

  1. 使用dropna()方法删除缺失值,返回新的Series对象;
  2. 使用series.isnull()以及series.notnull()方法,使用布尔筛选进行过滤出非缺失值;
print("-"*5 + "使用dropna()删除所有的缺失值" + "-"*5)
print(s.dropna())
print("-"*5 + "使用isnull()删除所有的缺失值" + "-"*5)
print(s[~s.isnull()])
print("-"*5 + "使用notnull()删除所有的缺失值" + "-"*5)
print(s[s.notnull()])

result:
-----使用dropna()删除所有的缺失值-----
0    1.0
1    2.0
3    4.0
dtype: float64
-----使用isnull()删除所有的缺失值-----
0    1.0
1    2.0
3    4.0
dtype: float64
-----使用notnull()删除所有的缺失值-----
0    1.0
1    2.0
3    4.0
dtype: float64

8.3 使用fillna()填充缺失值

  1. 使用指定值填充缺失值;
  2. 使用插值填充缺失值;
print("-"*5 + "原来的Series" + "-"*5)
print(s)
print("-"*5 + "指定填充值0" + "-"*5)
print(s.fillna(value = 0))

print("-"*5 + "向前填充ffill" + "-"*5)
print(s.fillna(method = "ffill"))
print("-"*5 + "向后填充bfill" + "-"*5)
print(s.fillna(method = "bfill"))

result:
-----原来的Series-----
0    1.0
1    2.0
2    NaN
3    4.0
dtype: float64
-----指定填充值0-----
0    1.0
1    2.0
2    0.0
3    4.0
dtype: float64
-----向前填充ffill-----
0    1.0
1    2.0
2    2.0
3    4.0
dtype: float64
-----向后填充bfill-----
0    1.0
1    2.0
2    4.0
3    4.0
dtype: float64

注意:

默认情况下,填充缺失值都会创建一个新的Series对象,如果希望直接在原来的Series上进行修改的话,可以使用下面两种方式:

  1. 直接进行赋值;
  2. 给fillna()函数添加一个新的参数,inplace = True参数;

9. Series排序

series的排序有两种:

  1. 根据索引进行排序,使用series.sort_index(ascending = True);
  2. 根据值进行排序,使用series.sort_value(ascending = True);

10. Series的描述性统计

Python-Pandas模块Series

Series的描述性统计

更多原创干货,欢迎关注我的知乎"触摸壹缕阳光"以及公众号"AI机器学习与深度学习算法"

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>