Pandas--Series类型数据的基本操作

1.1 Series

作者: Kevin Chen

文章目录

      • 1.1 Series
    • @[toc]
        • 1.1.1 创建series数组
          • a) 不自定义标签
          • b) 自定义标签
          • c) 创建随机series
        • 1.1.2 提取series的数据
        • 1.1.3 series数据的增删改
          • a) 添加
          • b) 删除
          • c) 修改
        • 1.1.4 常用series属性和方法
          • a) series的常用属性
          • b) series的常用方法
            • 1) series相关运算
            • 2) series数值判断
            • 3) series排序方法
            • 4) series复制方法

Series可以理解为一个一维的数组,只是 index 名称可以自己改动。类似于定长的有序字典,有 Index 和 value。

1.1.1 创建series数组
a) 不自定义标签
# 创建一个series
import pandas as pd

data1 = (1,2,3,4)		# 用元组构建序列
data2 = [5,6,7,8]		# 用列表构建序列
s1 = pd.Series(data1)
s2 = pd.Series(data2)
print(s1)
            """ 输出:   # 第一列为索引; 第二列为值; dtype: int64 标明值的数据类型 
            0    1	   # 虽然显示出来看很像是个二维数组 (4行2列);   但实际上是一维的, 第一列是索引
            1    2
            2    3
            3    4
            dtype: int64
            """
print(s2)
            """ 输出:
            0    5
            1    6
            2    7
            3    8
            dtype: int64
            """
b) 自定义标签
# 创建一个series, 并且自定义index (自定义的index常常被称为'标签')
import pandas as pd

# 方法1: 在pd.Series()函数中用index参数用列表给出索引
data = ['nana', 'kk', 'sisi']
s = pd.Series(data, index=['st01', 'st02', 'st03'])  # 在函数中使用index参数
print(s)
        """ 输出:
        st01    nana
        st02      kk
        st03    sisi
        dtype: object
        """

# 方法2: 用字典创建
data = {'s1': 'nana', 's2': 'kk', 's3': 'sisi'}		 # 以字典创建series时, 默认键既是标签
s = pd.Series(data)
print(s)
        """输出:
        s1    nana
        s2      kk
        s3    sisi
        dtype: object
        """
c) 创建随机series

创建随机整数series

import pandas as pd
import numpy as np

# random.randint的参数: low>>区间的下限,high>>区间的上限,size>>个数的多少

# 用random.randint方法随机创建 最小值为0, 最大值为10, 包含5个元素的整数序列
s1 = pd.Series(np.random.randint(low=0,high=10,size=5), index=['s1','s2','s3','s4','s5']) 
print(s1)
    """ 输出:
    s1    7
    s2    3
    s3    6
    s4    2
    s5    2
    dtype: int32
    """

创建随机小数series

import pandas as pd
import numpy as np

# random.rand函数可以返回一个或一组服从“0~1”均匀分布的随机样本值。随机样本取值范围是[0,1),不包括1

# 用random.rand方法随机创建 最小值为0, 最大值为10, 包含5个元素的小数序列
s = pd.Series(np.random.rand(5)*10, index=['s1','s2','s3','s4','s5'])	
# 将随机数乘以10, 使数值随机生成在10以内的小数
print(s)
    """ 输出:
    s1    1.703992
    s2    5.007543
    s3    1.370512
    s4    0.324551
    s5    7.296572
    dtype: float64
    """

创建符合状态分布的series

import pandas as pd
import numpy as np

# random.normal函数可以返回一个或一组正态分布的随机样本。参数为:平均值, 方差, 数据数量

# 随机生成5个符合平均值为10,方差为0.5的正态分布数值
s = pd.Series(np.random.normal(10,0.5,5), index=['s1','s2','s3','s4','s5'])
print(s)
""" 输出:
s1     9.798803
s2    10.175873
s3     9.937731
s4     9.837918
s5    10.154241
dtype: float64
"""
1.1.2 提取series的数据

series类型数据可以通过索引或标签进行提取单个元素

# 使用索引or标签检索元素  (有坑, 需注意)

# 当自定义标签为 字符串 时, 仍然能用索引查找元素
data = {'s1': 'nana', 's2': 'kk', 's3': 'sisi'}
s = pd.Series(data)
print(s['s1'])			# 输出'nana'
print(s[0])				# 输出'nana'

# 当自定义的标签为 int 时,会与index冲突, pandas默认使用标签, 而不是使用索引
s = pd.Series([1,2,3,4,5,6], index=[1, 2, 3, 4, 5, 6])
print(s[1])				# 输出1
print(s[0])				# 会报错...KeyError

series类型数据可以用索引或标签进行切片提取多个元素

# 用索引or标签对元素进行切片 (有坑, 需注意)
data = ['ss', 'kk', 'mm', 'tt']

# 用索引切片时,!!!!包前不包后!!!!
s1 = pd.Series(data)
print(s1[1:3])			# 输出kk, mm

# 用标签切片时,!!!!包前也包后!!!!
s2 = pd.Series(data, index=['1','2','3','4'])
print(s2['1':'3'])		# 输出ss, kk, mm
# 若自定义标签为字符串,那索引仍然能正常使用
print(s2[1:3])			# 输出kk, mm  (用索引, 包前不包后)

series类型数据可用mask掩码数组进行掩码提取多个元素:

  • 掩码来自于numpy库, 是用来处理数组的一种方法 (不导入numpy可用, pandas库中有)
  • 掩码数组也是一种数组,它本质上是对目标数组做一种特殊处理
  • 掩码通常用来表明被掩数据哪些要处理,哪些不必处理
# 用掩码数组mask获取数据
data = ['ss', 'kk', 'mm', 'tt']
s1 = pd.Series(data, index=['1','2','3','4'])

# 在使用掩码时, 索引&标签 都 !!!!包前也包后!!!!
print(s1[[0, 1, 2]])					# 输出: ss, kk, mm
print(s1[['3', '4']])					# 输出: mm, tt
print(s1[[True, True, False, True]])	# 输出: ss, kk, tt

用head()和tail()方法获取头部/尾部的多个元素

# 创建series
data = ['ss', 'kk', 'mm', 'tt', 'kq', 'ew', 'xs']
s = pd.Series(data, index=['s1','s2','s3','s4', 's5', 's6', 's7'])

# 获取头部3个数据	(若head方法内不写参数,则默认获得头部5个数据)
s.head(3)
    """ 输出:
    s1    ss
    s2    kk
    s3    mm
    dtype: object
    """

# 获取尾部到数2个数据	(若tail方法内不写参数,则默认获得尾部5个数据)
s.tail(2)
    """ 输出:
    s6    ew
    s7    xs
    dtype: object
    """

用for循环遍历series中的标签和元素值 (类似于字典)

data = ['ss', 'kk', 'mm', 'tt']
s2 = pd.Series(data, index=['s1','s2','s3','s4'])

# series有index属性, 可获得series的标签/索引
for i in s2.index:
    print(i)		# 输出: s1, s2, s3, s4
    
# series有values属性, 可获得series的元素值 
for i in s2.values:
    print(i)		# 输出: ss, kk, mm, tt

# 直接对series进行遍历获得其值
for i in s2:
    print(i)		# 输出: ss, kk, mm, tt

# series可以用items()方法返回 标签&元素
for i, v in s2.items():
    print(i)		# 输出: s1, s2, s3, s4
    print(v)		# 输出: ss, kk, mm, tt
1.1.3 series数据的增删改
# 先创建一个series
data = {'s1': 'nana', 's2': 'kk', 's3': 'sisi'}
a = pd.Series(data)
a) 添加

用键值对方法添加单个元素

  • 改变原有的series !!!
a['s4']='lalo'
print(a)

"""输出:
s1    nana
s2      kk
s3    sisi
s4    lalo
dtype: object
"""

用append()方法在series中添加多个元素

  • 使用 append() 方法时, 添加的数据必须与原数据是相同类型的

  • 不会改变原series !!! 产生一个新series

# 向序列中添加新数据{'s5': 'wawa', 's6': 'yoyo'}, 带有自定义标签
b = a.append(pd.Series({'s5': 'wawa', 's6': 'yoyo'}))  # 不会修改原series, 而是返回一个新的series
print(a, b)		
    """
a:   s1    nana
     s2      kk						# 可见a序列没有变化, append()不会修改原本的a序列
     s3    sisi
     s4    lalo
     dtype: object,

b:   s1    nana
     s2      kk
     s3    sisi						# b序列中出现了添加的数据
     s4    lalo
     s5    wawa
     s6    yoyo
     dtype: object
     """


# 向序列中添加新数据['wawa', 'yoyo'], 不带自定义标签
c = a.append(pd.Series(['wawa', 'yoyo']))
print(c)
    """
c:  s1    nana
    s2      kk
    s3    sisi
    s4    lalo
    0     wawa						# 由于没有自定义标签, 所以系统默认从0开始添加索引
    1     yoyo
    dtype: object
    """
print(c[0])						# 输出: wawa
print(c[2])						# 会报错....KeyError
b) 删除

用del删除series中的单个元素

  • 改变原series
print(a)
    """a序列含有以下数据:
    s1    nana
    s2      kk
    s3    sisi
    s4    lalo
    dtype: object
    """

# 用del输出标签为's1'的元素
del a['s1']
print(a)

    """删除后, a序列输出:
    s2      kk
    s3    sisi
    s4    lalo
    dtype: object
    """

用drop()删除series中的多个数据

  • 不会改变原series, 而是产生一个新series
print(a)
    """a序列含有以下数据:
    s1    nana
    s2      kk
    s3    sisi
    s4    lalo
    dtype: object
    """

# 删除a序列中's1'标签的数据 (用drop方法进行单数据删除)
b = a.drop('s1')
print(a, b)
    """ 输出:
a:  s1    nana
    s2      kk
    s3    sisi
    s4    lalo
    dtype: object
    
b:  s2      kk
    s3    sisi
    s4    lalo
    dtype: object
    """

# 删除a序列中's1'和's2'标签的数据  (用drop方法进行多数据删除)
c = a.drop(['s1', 's2'])
print(a, c)
    """ 输出:
a:  s1    nana
    s2      kk
    s3    sisi
    s4    lalo
    dtype: object
    
c:  s3    sisi
    s4    lalo
    dtype: object
    """
    
# 用series的索引删除单个数据 (只能用索引, 不能用标签)
d = a.drop(c.index[2])
print(d)
    """
    s1    nana
    s2      kk
    s4    lalo
    dtype: object
    """
    
# 用series的索引删除多个数据 (只能用索引, 不能用标签)    
e = a.drop(a.index[[1,2]])
print(e)
    """
    s1    nana
    s4    lalo
    dtype: object
    """
c) 修改

通过标签/索引 修改series内单个元素的值

# 创建一个series
data = ['ss', 'kk', 'mm', 'tt']
s = pd.Series(data, index=['s1','s2','s3','s4'])

# 将标签为s1的值修改为'ww'   修改单个元素值
s['s1'] = 'ww'
print(s)
    """直接修改原series
    s1    ww
    s2    kk
    s3    mm
    s4    tt
    dtype: object
    """

通过掩码 修改series内多个元素的值

# 将标签为's1'和's3'的值修改为'dd'和'll'     使用的是掩码的原理
s[['s1', 's3']] = 'dd', 'll'
print(s)
    """直接修改原series
    s1    dd
    s2    kk
    s3    ll
    s4    tt
    dtype: object
    """
1.1.4 常用series属性和方法
a) series的常用属性
# 创建两个series用于测试属性

# s1有自定义标签, 元素为字符串
data1 = ['ss', 'kk', 'mm', 'tt']
s1 = pd.Series(data1, index=['1', '2', '3', '4'], name='s序列')
# s2无自定义标签, 元素为整数
data2 = [1, 2, 3, 4, 5]
s2 = pd.Series(data2)

series的name属性

  • 在创建series的时候, 可以添加一个name参数作为series的名字, 创建上方s1序列的创建
print(s1.name)				# 输出:    's序列'

series的value属性, 以数组 (ndarray)形式返回series内的元素值

  • ndarray: ndarray对象是用于存放同类型元素的多维数组,是numpy中的基本对象之一
# values属性, 返回series元素值 (不是列表, 是ndarray对象)
print(s1.values)		# 输出: ['ss' 'kk' 'mm' 'tt']
print(s2.values)		# 输出: [1 2 3 4 5]


# 可以用values属性判断series中是否存在某数据
# 例: 判断b序列中是否存在'wawa'
print('wawa'in b.values)		# 输出: True
# 用values可以以ndarry形式返回序列中的数据

series的index属性, 以数组 (ndarray)形式返回series内的 索引或标签

# index属性, 返回标签/索引的值,和类型
print(s1.index)		# 输出: Index(['1', '2', '3', '4'], dtype='object')	返回标签
print(s2.index)		# 输出: RangeIndex(start=0, stop=5, step=1)	返回索引

series的dtype属性, 可以得到元素的数据类型

object数据类型是什么?

  • 当一个数组中都是同一个数据类型时, 系统能给出那个数据类型的名称 ( 比如都是整数类型时,会给出inte64 )
  • 但是当一个数组中存在不同的数据类型时, 系统会返回object ( 由于字符串的长度不定, 所以字符串被认为是object )
  • object这是一种通用的数据类型, 在没有明确的指定类型的情况下, 所有的数据都可以认为是object型
# dtype属性, 返回series数据的类型
print(s1.dtype)		# 输出: object
print(s2.dtype)		# 输出: int64

series的size属性, 可以得到series含有的元素数量

# size属性, 返回series的长度(元素数量)
print(s1.size)		# 输出: 4
print(s2.size)		# 输出: 5

series的ndim属性, 返回维度, series永远是一维

# ndim属性, 返回series的维度 (series本身就是个一维的数组,所以没啥用)
print(s1.ndim)		# 输出: 1
print(s1.ndim)		# 输出: 1

series的shape属性, 可以获得series含有的元素数量

# shape属性, 以元组形式返回各维度的大小(元素数量), (3维: 页,行,列), (2维: 行,列), (1维: 列,)
print(s1.shape)		# 输出: (4,)
print(s2.shape)		# 输出: (5,)
b) series的常用方法
1) series相关运算

sum() 方法

  • 获取dtype为数字类型的series的所有值的和
  • 注意! 如果dtype为object, 会报错
# 数字类型的series求和
s1 = pd.Series(data=[1.1,2,3.0,4,5.2],index=["a","b","c","d","e"])
print(s1.sum())		# 输出  15.3

# 数字类型的object求和
s2 = pd.Series(data=[1.1,2,3.0,4,"5.2"],index=["a","b","c","d","e"])
s2.sum()			# 报错...TypeError

Series之间的运算

  • 支持Numpy数组运算
  • 在运算中自动对齐不同索引的数据
  • 如果索引不对应,则补NaN
# 创建两个series
s1 = pd.Series(data=[1,2,3,4,5],index=["a","b","c","d","e"])
s2 = pd.Series(data=[1,2,3,4,5],index=["a","b","c","d","f"])

# 将s1和s2相加
s = s1 + s2
print(s)
    """输出s:
    a    2.0
    b    4.0
    c    6.0
    d    8.0
    e    NaN
    f    NaN
    dtype: float64
    """
    
# 将s1与s2相乘
s = s1 * s2
print(s) 
    """ 输出s:
    a     1.0
    b     4.0
    c     9.0
    d    16.0
    e     NaN
    f     NaN
    dtype: float64
    """
# 对s1序列进行取余运算
s = s1 % 2
print(s)
    """ 输出s:
    a    1
    b    0
    c    1
    d    0
    e    1
    dtype: int64
    """

# series之间还支持/, // 等运算 

apply() 与 map() 方法

  • 在series中, apply与map方法的功能相同
  • apply()方法, 让函数作用在一维数据的每个元素上
  • map()方法, 将函数作用于Series的每一个元素上
# 创建series
s1 = pd.Series(data=[1,2,3,4,5],index=["a","b","d","e","f"])

# 创建一个函数,函数内的传参为series的元素
def func(item):
    return 10 * item

# map()函数
s = s1.map(func)
print(s)
    """ 输出:
    a    10
    b    20
    d    30
    e    40
    f    50
    dtype: int64
    """
# apply()函数
s = s1.apply(func)
print(s)
    """ 输出:
    a    10
    b    20
    d    30
    e    40
    f    50
    dtype: int64
    """
2) series数值判断

isnull() 与 notnull() 方法, 用于判断元素值是否为空

"""
isnull()  	# 缺失的数据返回的布尔值为True
notnull() 	# 缺失的数据返回的布尔值为False
"""
# 创建一个含有2个NaN的series
import pandas as pd
import numpy as np
s1 = pd.Series(data=[1,np.NaN,3,4,np.NaN],index=["a","b","c","d","e"])

# isnull()方法
print(s1.isnull())				# 输出所有数据是否为NaN
    """ 输出:
    a    False
    b     True
    c    False
    d    False
    e     True
    dtype: bool
    """
print(s1.isnull().sum())		# 用sum()方法输出NaN数据的数量
	# 输出: 2

# notnull()方法
print(s1.notnull())				# 输出所有数据是否不为NaN
	""" 输出:
	a     True
    b    False
    c     True
    d     True
    e    False
    dtype: bool
	"""
print(s1.notnull().sum())		# 用sum()方法输出不为NaN数据的数量
	# 输出: 3

用unique()方法对series的值进行去重

# 创建series
data = ['ss', 'kk', 'ss', 'tt', 'kk', 'ew', 'tt']
a = pd.Series(data, index=['s1','s2','s3','s4', 's5', 's6', 's7'])

# 对a序列去除重复值, 不会改变原series, 输出一个类型为ndarray的新对象
b = a.unique()
print(b)			#输出: array(['ss', 'kk', 'tt', 'ew'], dtype=object)

argmax() 与 argmin() 方法

  • argmax() 返回series中最大值的位置 (第几个位置的值是最大值, 从0开始算)
  • argmin() 返回series中最小值的位置 (第几个位置的值是最大值, 从0开始算)
# 创建series
s1 = pd.Series(data=[3,2,1,4,5],index=["a","b","d","e","f"])

print(s1.argmax())			# 输出: 4  >>>  第五个元素的值最大(5)
print(s1.argmin())			# 输出: 2  >>>  第三个元素的值最大(1)
3) series排序方法

reindex()方法: 用于添加新标签,以及修改标签顺序

  • index参数, fill_value参数
# 创建测试序列
s1 = pd.Series(data=[1,2,3,4,5],index=["a","b","d","e","f"])

# index参数: 用于添加新标签,以及修改标签顺序
s = s1.reindex(index=['a','b','c','d','e','f','g','h'])
print(s)
    """ 输出:
    b    2.0
    a    1.0			# 可见标签顺序修改后, 相应值的顺序也改变了
    c    NaN
    d    3.0
    e    4.0
    f    5.0
    g    NaN			# 新标签对应的值为NaN
    h    NaN
    dtype: float64
    """
# fill_value参数: 用于填充新标签对应的值
s1['e'] = np.NaN 	# 将e标签对应的值修改为NaN
s = s1.reindex(index=['a','b','c','d','e','f','g','h'], fill_value=6)
print(s)    
    """ 输出:
    a    1.0
    b    2.0
    c    6.0
    d    3.0
    e    NaN			# 可见原本series中的NaN不会被填充掉
    f    5.0
    g    6.0			# 其他新标签对应的值, 全部被填充为6
    h    6.0
    dtype: float64
    """

sort_index() 函数

  • 将series根据标签/索引的顺序, 重新排序
  • 对某些有序object类标签也同样有效
# 创建一个数字类型标签的series
s1 = pd.Series(data=["a","b","d","e","f"],index=[3,2,1,4,5])
# 用倒序进行排序ascending=False, (默认为正序,从小到大)
s = s1.sort_index(ascending=False)
print(s)
    """ 输出:
    5    f
    4    e
    3    a
    2    b
    1    d
    dtype: object
    """
    
# 创建一个字符串类型标签的series    
s1 = pd.Series(data=["a","b","d","e","f"],index=['cc', 'bb', 'aa','dd','ee'])
# 用正序进行排序ascending=True, (默认为正序,从小到大)
s = s1.sort_index(ascending=True)
print(s)
    """ 输出:
    aa    d
    bb    b
    cc    a
    dd    e
    ee    f
    dtype: object
    """

sort_value() 函数

  • 将series根据元素的值的顺序, 重新排序
  • 对某些有序object类值也同样有效
# 创建索引
s1 = pd.Series(data=[4,3,2,1,5],index=['cc', 'bb', 'aa','dd','ee'])
# 根据元素的值,将series排序
s = s1.sort_values(ascending=True)
print(s)
    """ 输出:
    dd    1
    aa    2
    bb    3
    cc    4
    ee    5
    dtype: int64
    """

rank() 方法

  • 输出series的每个元素的值的排列名次
  • 对某些有序object类值也同样有效
# 创建序列
s1 = pd.Series(data=['c','c','a','d','e'],index=['s1','s2','s3','s4','s5'])
# 输出序列中每个元素的名次, 根据从大到小排列, 排列同名次的按平均值输出
s = s1.rank(ascending=False, method='average')
print(s)
    """ 输出:
    s1    3.5				# 有两个'c', 并列排名第三第四名, 平均后就是3.5
    s2    3.5				# 有两个'c', 并列排名第三第四名, 平均后就是3.5
    s3    5.0
    s4    2.0
    s5    1.0				# 'e'最大, 所以排名为1
    dtype: float64
    """
# 创建序列   
s1 = pd.Series(data=[4,3,3,1,5],index=['s1','s2','s3','s4','s5'])
# 输出序列中每个元素的名次, 根据从小到大排列, 排列名次相同的按最小数字输出
s = s1.rank(method='min')
print(s)
    """ 输出:
    s1    4.0
    s2    2.0				# 有两个3, 并列派第二第三名, 按最小数字输出, 既是2
    s3    2.0				# 有两个3, 并列派第二第三名, 按最小数字输出, 既是2
    s4    1.0				# 1最小, 所以排第一名
    s5    5.0
    dtype: float64
    """
    
# method参数有: min, max, average, first, last
4) series复制方法

copy() 方法, 复制一个Series

# 先创建一个series
s1 = pd.Series(data=[1,2,3,4,5],index=["a","b","c","d","e"])
# 复制
s = s1.copy()
print(s)
    """
    a    1
    b    2
    c    3
    d    4
    e    5
    dtype: int64
    """

你可能感兴趣的:(python,数据分析,numpy,数据建模)