Series是一种类似于一维数组的对象,由下面两个部分组成:
- values:一组数据(ndarray类型)
- index:相关的数据索引标签
Series的创建
1.由列表或numpy数组创建; 默认索引为0到N-1的整数型索引
from pandas import Series # 导入Series
# 不指定index;会加默认索引, 数据类型会根据你提供的数据推断.
l = [1, 2, 3, 4]
s = Series(data=l)
s
"""
0 1
1 2
2 3
3 4
dtype: int64
"""
# 通过values获取到series的values
s.values # array([1, 2, 3, 4], dtype=int64)
# 获取索引;索引0-4, 步长为1
s.index # RangeIndex(start=0, stop=4, step=1)
# 通过设置index参数指定索引
list('abcd') # ['a', 'b', 'c', 'd']
s.index = list('abcd')
s
"""
a 1
b 2
c 3
d 4
dtype: int64
"""
# 通过索引去访问对应的values
s['b'] # 2
s['b'] = 10 # 设置索引b的值
s
"""
a 1
b 10
c 3
d 4
dtype: int64
"""
l # [1, 2, 3, 4]; 可以看到列表l的元素没有改变
注意:由ndarray创建的是引用,而不是副本。对Series元素的改变也会改变原来的ndarray对象中的元素
import numpy as np
n = np.array([1, 2, 3, 4])
s2 = Series(n)
s2
"""
0 1
1 2
2 3
3 4
dtype: int32
"""
s2[0] = 66 # 设置索引0的值
s2
"""
0 66
1 2
2 3
3 4
dtype: int32
"""
n # array([66, 2, 3, 4]); 可以看到ndarray中的元素已经被改变
2.由字典创建
可以把Series看成一个定长的有序字典;字典的key就相当于series的index, 字典的value就相当于series的value
# 会默认把字典的key作为series的index, 字典的value作为index对应的value
s3 = Series(data={'a': 1, 'b': 2, 'c': 3, 'd': 4})
s3
"""
a 1
b 2
c 3
d 4
dtype: int64
"""
Series的索引和切片
可以使用中括号取单个索引 => 此时返回的是元素类型,或者中括号里一个列表取多个索引 => 此时返回的仍然是一个Series类型。分为显示索引和隐式索引:
1.显式索引:
- 使用index中的元素作为索引值
- 使用.loc[](推荐写法)
注意:此时是闭区间
s1 = Series({'语文': 150, '数学': 150, '英语': 150, '理综': 300})
s1
"""
语文 150
数学 150
英语 150
理综 300
dtype: int64
"""
# 不推荐写法
s1['语文'] # 150
# 推荐写法
s1.loc['语文'] # 150
# 显式切片索引, 显式切片是全闭区间. 不推荐
s1['语文': '数学']
"""
语文 150
数学 150
dtype: int64
"""
# 推荐写法
s1.loc['语文': '数学']
"""
语文 150
数学 150
dtype: int64
"""
# 使用条件来过滤 Series 中的元素
s1.loc[s1>150]
"""
理综 300
dtype: int64
"""
2. 隐式索引:
- 使用整数作为索引值
- 使用.iloc[](推荐写法)
注意:此时是半开区间
# 不推荐写法
s1[0] # 150
# 推荐写法
s1.iloc[0] # 150
s1.index[0] # '语文'
# 隐式索引切片, 隐式切片是左闭右开
s1.iloc[0:2]
"""
语文 150
数学 150
dtype: int64
"""
Series的属性
s = Series(data=np.random.randint(0, 150, size=(5,)), index=list('abcde'))
s
"""
a 99
b 54
c 0
d 30
e 21
dtype: int32
"""
# shape 属性返回一个元组,其中包含 Series 对象的维度信息
s.shape # (5,)
# size 返回 Series 对象中的元素总数
s.size # 5
# index 返回 Series 对象的索引,即行标签
# 具备列表的性质, 就把index当成列表去使用.
s.index # Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
# values 返回 Series 对象中的数据部分,即 Series 的值部分
s.values # array([ 7, 31, 108, 94, 47])
# head(n) 返回前n个元素; 不传默认返回前5个元素
s.head(2)
"""
a 78
b 105
dtype: int32
"""
# tail(n) 返回最后n个元素,不传默认返回最后五个元素
s.tail(2)
"""
d 107
e 146
dtype: int32
"""
# Series对象本身及其实例都有一个name属性
s.name = "series"
s
"""
a 101
b 93
c 149
d 53
e 29
Name: series, dtype: int32
"""
isnull(),notnull() 检测缺失数据
当索引没有对应的值时,可能出现缺失数据显示NaN(not a number)
s = Series(data=[1, 2, 3, None], index=list('abcd'))
s
"""
a 1.0
b 2.0
c 3.0
d NaN
dtype: float64
"""
s.loc['d'] # nan
# nan返回True
s.isnull()
"""
a False
b False
c False
d True
dtype: bool
"""
# 不是nan返回True
s.notnull()
"""
a True
b True
c True
d False
dtype: bool
"""
Series的运算
1. 适用于numpy的数组运算也适用于Series
# series和单个数字运算, 每个元素分别和这个数字进行运算.
s + 1
"""
a 2.0
b 3.0
c 4.0
d NaN
dtype: float64
"""
2. Series之间的运算
- 在运算中自动对齐不同索引的数据
- 如果索引不对应,则补NaN
s1 = Series(data=[1, 2, 3, 4], index=list('abcd'), name='s1')
s2 = Series(data=[4, 5, 6, 7], index=list('cdef'), name='s2')
display(s1, s2)
"""
a 1
b 2
c 3
d 4
Name: s1, dtype: int64
c 4
d 5
e 6
f 7
Name: s2, dtype: int64
"""
# 索引相同的元素进行运算, 索引不同的元素, 返回NaN.
s1 + s2
"""
a NaN
b NaN
c 7.0
d 9.0
e NaN
f NaN
dtype: float64
"""
3. 使用add()函数
- add可以保留所有的index索引的数
# series中索引不同的使用0填充
s1.add(s2, fill_value=0)
"""
a 1.0
b 2.0
c 7.0
d 9.0
e 6.0
f 7.0
dtype: float64
"""
Series运算和ndarray运算的规则区别
- series运算是没有广播机制的. ndarray运算有广播机制.
- series运算是索引相同的位置进行运算.
- ndarray通过广播机制, 把运算的ndarray的形状(shape)变成一样, 然后对应位置的元素进行运算.