【数据分析专栏之Python篇】五、pandas数据结构之Series
前言
大家好!本期跟大家分享的知识是 Pandas 数据结构—Series。
一、Series的创建
Series 是一种类似于一维数组的对象,由下面两部分组成:
values
:一组数据,ndarray 类型index
:数据索引
顾名思义,我们在创建 Series
对象时,需要传递一组数据,该数据大多数时候是可迭代对象。因此,下面三种创建方式都是将数据传入到 Series 方法中。
1.1 列表数组创建
以列表作为数据创建 Series。
list1 = list('ABCD') # 创建列表
s =pd.Series(list1) # 传递列表数据到 Series 方法中
print(s)
print(type(s.values))
print(type(s.index))
###########结果###########
0 A
1 B
2 C
3 D
dtype: object
<class 'numpy.ndarray'>
<class 'pandas.core.indexes.range.RangeIndex'>
以数组作为数据创建 Series。
n = np.array(range(5,10))
s2 = pd.Series(n)
s2
###########结果###########
0 5
1 6
2 7
3 8
4 9
dtype: int32
1.2 字典创建
前两种方式,都是只传递了数据,那么索引是默认索引(0 ~ N-1);下面的字典创建方式,则是以字典的键为索引,字典的值为数据。
d = {
'a':11,'b':22,'c':33,'d':44
}
s = pd.Series(d)
s
###########结果###########
a 11
b 22
c 33
d 44
dtype: int64
1.3 通过标量创建
s = pd.Series(100,index=range(5))
s
###########结果###########
0 100
1 100
2 100
3 100
4 100
dtype: int64
二、Series索引
从以上 Series 的创建中我们可以看出,Series 的索引是可以修改的
。我们先来探讨以下索引的作用。
-
获取元素:有多种获取方式,s.索引名,s[‘索引名’],s.loc[‘索引名’]
-
允许修改:(为
s.index
重新赋值即可,注意前后数量一致)
显式即表示使用索引名称的方式,隐式即表示使用序号的方式。后面的显式切片和隐式切片也是同理。
2.1 显式索引
取单个值时,三种方式:(假设 Series
对象名为 s
)
- s.索引名(数字索引不能用这种方式)
- s[‘索引名’]
- s.loc[‘索引名’]
取多个值时,返回一个新的 Series 对象,两种方式(也就是加中括号):
- s.[[‘索引名1’,‘索引名2’]]
- s.loc[[‘索引名1’,‘索引名2’]]
s = pd.Series(np.array(range(5,10)),index=list('abcde'),name='number')
print(s)
display(s.a,s['a'],s.loc['a'])
###########结果###########
a 5
b 6
c 7
d 8
e 9
Name: number, dtype: int32
5
5
5
2.2 隐式索引
隐式索引和显示索引的区别就是它通过数字来获取值。因为是数字,因此 s.number
这种方式肯定 不能用了 ,其他都相同。
取单值,两种方式:
- s[number]
- s.iloc[number]
取多值,两种方式:
- s[[number1,number2]]
- s.iloc[[number1,number2]]
s = pd.Series(np.array(range(5,10)),index=list('abcde'),name='number')
print(s)
print('取单值')
print(s[1])
print(s.iloc[1])
print('取多值')
print(s[[1,2]])
print(s.iloc[[1,2]])
###########结果###########
a 5
b 6
c 7
d 8
e 9
Name: number, dtype: int32
a 5
b 6
c 7
d 8
e 9
Name: number, dtype: int32
取单值
6
6
取多值
b 6
c 7
Name: number, dtype: int32
b 6
c 7
Name: number, dtype: int32
三、Series切片
切片操作是获取一个新的 Series 对象的操作,显式切片是为左闭右闭,隐式切片时为左闭右开。
2.1 显式切片
两种方式:
- s[索引名1:索引名2]
- s.loc[索引名1:索引名2]
2.2 隐式切片
两种方式:
- s[number1:number2]
- s.iloc[number1:number2]
s = pd.Series({
'yw':100,
'math':150,
'eng':110,
'Python':130
})
print('数据:',end='')
print('-'*10)
print(s)
print('-'*10)
print('显式切片')
print(s['yw':'math'])
print('-'*10)
print(s.loc['yw':'math'])
print('-'*10)
print('隐式切片')
print(s[0:1])
print('-'*10)
print(s.iloc[0:1])
###########结果###########
数据:----------
yw 100
math 150
eng 110
Python 130
dtype: int64
----------
显式切片
yw 100
math 150
dtype: int64
----------
yw 100
math 150
dtype: int64
----------
隐式切片
yw 100
dtype: int64
----------
yw 100
dtype: int64
四、Series基本属性和方法
Series基本属性和方法是让我们更好了解数据组成的手段。
4.1 属性
属性 | 作用 |
---|---|
s.shape | 查看数据行列 |
s.ndim | 查看维度,Series 就是一维,ndim 恒等于1 |
s.size | 查看数据总数 |
s.index | 查看索引 |
s.values | 查看数据 |
s.name | 查看 Series 对象的 name,若未设定则为空 |
4.2 方法
方法 | 功能 |
---|---|
s.head() | 查看前5条数据,若传入数字 n ,则查看前 n 条 |
s.tail() | 查看后5条数据,若传入数字 n ,则查看后 n 条 |
s.isnull() | 判断数据是否为空,空的为 True ,不空的为 False |
s.notnull() | 判断数据是否不空,空的为 False ,不空的为 True |
4.3 案例——使用 bool 值去除空值
原理:Series 切片可以再传入一个 Series 对象,该 Series 对象索引要和原来相同,那么值为 False 的将不会被取出。
请看示例:
s = pd.Series(['a','e','f','b'])
s[pd.Series([True,True,False,True])]
###########结果###########
0 a
1 e
3 b
dtype: object
如果改为:
s = pd.Series(['a','e','f','b'])
s[pd.Series([True,True,False,True],index=list('abcd'))]
###########结果###########
那么将会报错:
IndexingError Traceback (most recent call last)
E:\Temp/ipykernel_15804/3537358820.py in <module>
1 s = pd.Series(['a','e','f','b'])
----> 2 s[pd.Series([True,True,False,True],index=list('abcd'))]
D:\PF\Anaconda3\lib\site-packages\pandas\core\series.py in __getitem__(self, key)
1001
1002 if com.is_bool_indexer(key):
-> 1003 key = check_bool_indexer(self.index, key)
1004 key = np.asarray(key, dtype=bool)
1005 return self._get_values(key)
D:\PF\Anaconda3\lib\site-packages\pandas\core\indexing.py in check_bool_indexer(index, key)
2550 indexer = result.index.get_indexer_for(index)
2551 if -1 in indexer:
-> 2552 raise IndexingError(
2553 "Unalignable boolean Series provided as "
2554 "indexer (index of the boolean Series and of "
IndexingError: Unalignable boolean Series provided as indexer (index of the boolean Series and of the indexed object do not match).
下面是 Series 去除空值的案例。
s = pd.Series(['zhangsan','lisi','a',np.NAN,None])
print('数据:'+'-'*10)
print(s)
conditon = s.isnull()
print('判空情况:'+'-'*10)
print(conditon)
# 使用 bool 值索引过滤数据
s = s[~conditon]
print('过滤结果:'+'-'*10)
print(s)
###########结果###########
数据:----------
0 zhangsan
1 lisi
2 a
3 NaN
4 None
dtype: object
判空情况:----------
0 False
1 False
2 False
3 True
4 True
dtype: bool
过滤结果:----------
0 zhangsan
1 lisi
2 a
dtype: object
五、Series运算
Series 运算包括算术运算和 Series 对象之间运算。算术运算是针对每一个元素的,有 +、-、*、/、 //、 %、 ** 等,这里不再赘述。Series 对象间的运算,只要记住,索引一个有一个没有时,计算值为 NaN
,其他按照算术运算计算即可。
- 算术运算
s = pd.Series(np.array(range(5,10)))
print(s)
s * 10
###########结果###########
0 5
1 6
2 7
3 8
4 9
dtype: int32
0 50
1 60
2 70
3 80
4 90
dtype: int32
- Series对象间的运算
s1 = pd.Series(np.array(range(5,10)))
s2 = pd.Series([3,6,10,12])
print(s1)
print(s2)
s1 + s2 # 索引一个有一个没有时,计算值为 NaN
###########结果###########
0 5
1 6
2 7
3 8
4 9
dtype: int32
0 3
1 6
2 10
3 12
dtype: int64
0 8.0
1 12.0
2 17.0
3 20.0
4 NaN
dtype: float64
六、Series多层行索引
6.1 Series多层索引的构建
Series 不仅支持单层索引,还支持多层索引。最简单的实现方式就是将 index
设置成多维。
下面以二级行索引为例:
s = pd.Series(np.random.randint(60,100,6),index=[['语文','语文','语文','数学','数学','数学'],['小明','小红','小丽','小明','小红','小丽']])
print(s)
###########结果###########
语文 小明 90
小红 72
小丽 97
数学 小明 81
小红 74
小丽 84
dtype: int32
6.2 Series多层索引的索引和切片操作
对于 Series
多层索引的索引和切片操作,只要记住以下两点:
- 要先取第一层,再取第二层,不能直接取第二层索引
- 获取到第一层之后,就是一个普通的单层索引 Series
- 隐式索引,直接得到数
具体的方式,还是索引和切片都分为显式和隐式,下面通过一个案例来演示。
索引:
s = pd.Series(np.random.randint(60,100,6),index=[['语文','语文','语文','数学','数学','数学'],['小明','小红','小丽','小明','小红','小丽']])
print(s)
# 索引
print('显式索引:'+'-'*10)
print(s['语文']) # 获取到单层 Series
print(s.loc['语文'])
print(s['语文']['小明'],s.loc['语文']['小明']) # 获取到单个值
print('隐式索引:'+'-'*10)
print(s.iloc[0])
print(s[0]) # 获取到单个值
###########结果###########
语文 小明 94
小红 95
小丽 60
数学 小明 66
小红 84
小丽 76
dtype: int32
显式索引:----------
小明 94
小红 95
小丽 60
dtype: int32
小明 94
小红 95
小丽 60
dtype: int32
94 94
隐式索引:----------
94
94
切片:
s = pd.Series(np.random.randint(60,100,6),index=[['语文','语文','语文','数学','数学','数学'],['小明','小红','小丽','小明','小红','小丽']])
s = s.sort_index()
print(s)
print('显式切片'+'-'*10)
print(s['数学':'语文'])
print(s.loc['数学':'语文'])
print('隐式切片'+'-'*10)
print(s[0:2])
print(s.iloc[0:2])
###########结果###########
数学 小丽 67
小明 64
小红 92
语文 小丽 84
小明 99
小红 82
dtype: int32
显式切片----------
数学 小丽 67
小明 64
小红 92
语文 小丽 84
小明 99
小红 82
dtype: int32
数学 小丽 67
小明 64
小红 92
语文 小丽 84
小明 99
小红 82
dtype: int32
隐式切片----------
数学 小丽 67
小明 64
dtype: int32
数学 小丽 67
小明 64
dtype: int32
结语
💕 本期跟大家分享的 “芝士” 就到此结束了,关于 Series 数据结构,你学会了吗?✨
🍻 我是南晨曦,在学习的路上一直前行,期待与你一起进步。~ 🍻
🔥如果文中有些地方不清楚的话,欢迎联系我,我会给大家提供思路及解答。🔥