Series 用于存储一列有索引的数据,相当于只有一列的一维阵列。
创建
pandas.Series(data=None, index=None, dtype=None, name=None, copy=False, fastpath=False)
参数:
data:要创建的数据,列表、字典等可迭代对象,以及按顺序存储的数据均可(必填)。
index:索引标签,可使用默认值(默认值是数字0,1,2…),如果设置索引,索引数据长度必须与第一个参数data相同。
dtype:指定输出数据的类型,比如‘str’,可以使用默认值,程序将自己根据原始数据推断类型。
name:数据的名称。(print(s.name) 会输出这个参数的值,如果在DataFrame中也就是列名。)
copy: 赋值输入的数据;(很少用到)
fastpath:快捷路径。(官方文档也没介绍,鬼知道什么用)
注:
1、index 索引不必是唯一的,但必须是一个不可变的类型。比如字符串、数组等
2、Series 既支持基于整数的索引(s[1]),也支持基于标签的索引s[index]
3、ndarray的统计方法和排除数据的方法都可以使用与Series
举例:
1、导入模块,创建 Series
import pandas
import numpy
cba = pandas.Series(data=[1, 3, 9, 3, 5], index=['a', 'b', 'a', 'c', 'd'], dtype='float64', name='abc')
print(cba) # 输出数据
[output]
a 1.0
b 3.0
a 9.0
c 3.0
d 5.0
Name: abc, dtype: float64
原本都是int数字,但是被强制转换了float; 可以看到:Name: abc(列名)
2、切片获取元素
print('cba[2]---', cba[2]) # 获取单个元素
print('--'*10) # 分割线
print('cba[0:2]---', type(cba[0:2]), "\n", cba[0:2]) # 获取多个元素
print('--'*10) # 分割线
print('cba.iloc[0:2]---', "\n", cba.iloc[0:2]) # iloc也同样好用
print('--'*10) # 分割线
print('cba.["a"]---', "\n", cba['a']) # 使用索引标签获取元素
print('--'*10) # 分割线
print('cba.[["a", "c"]]---', "\n", cba[["a", "c"]]) # 获取多个元素
print('--'*10) # 分割线
print('cba.loc[["a", "c"]]---', "\n", cba.loc[["a", "c"]]) # loc也同样好用
[output]
cba[2]--- 9.0
--------------------
cba[0:2]--- <class 'pandas.core.series.Series'>
a 1.0
b 3.0
Name: abc, dtype: float64
--------------------
cba.iloc[0:2]---
a 1.0
b 3.0
Name: abc, dtype: float64
--------------------
cba.["a"]---
a 1.0
a 9.0
Name: abc, dtype: float64
--------------------
cba.[["a", "c"]]---
a 1.0
a 9.0
c 3.0
Name: abc, dtype: float64
--------------------
cba.loc[["a", "c"]]---
a 1.0
a 9.0
c 3.0
Name: abc, dtype: float64
这里需要注意的是,使用数字和索引标签切片都可以获取一个元素,但是数字切边必然是一个元素,但是索引标签就不一定了,如果有重复的索引标签,那么获取的到数据仍然是一个Series;获取多个元素的切片结果也是Series;
3、修改数据
cba[2] = cba[2] + 10
print(cba[2])
[output]
19.0
目前是数据是int格式,如果是字符串呢?再换个数据:
data = ['TMJT20012278',
'TMJT20012278',
'TMJT20012278-B1',
'TMJT20012278-B2',
'TMJT20012764',
'ZJJT20011910-B1',
'ZJJT20011910-B2']
cba = pandas.Series(data=data, index=['a', 'b', 'a', 'c', 'd', 'c', 'd'], dtype='str', name='abc')
print(cba[1])
cba[1] = cba[1] + 'lll'
print(cba[1])
print('--'*10) # 分割线
print(cba['b'])
cba['b'] = cba['b'] + 'kkk'
print(cba['b'])
print('--'*10) # 分割线
[output]
TMJT20012278
TMJT20012278lll
--------------------
TMJT20012278lll
TMJT20012278lllkkk
--------------------
目前为止一切正常,但是坑来了。
一个小坑
上面的字符串修改元素只是简单的索引修改,实际应用中数据是很多的,可能需要遍历来修改:
print(cba.index)
for r in cba.index:
print(cba[r])
cba[r] = cba[r].partition('-B')[0] # 切割元素为三段,只取第一段
[output]
Index(['a', 'b', 'a', 'c', 'd', 'c', 'd'], dtype='object')
a TMJT20012278
a TMJT20012278-B1
Name: abc, dtype: object
AttributeError: 'Series' object has no attribute 'partition'
咦? 报错? 前面的例子中使用索引是可以取出元素并且重新修改赋值的呀!其实这是个低级错误,因为索引有重复索引,重复索引取出来的数据是Series,而上面元素修改的时候用到了partition()这是个str的方法,不能用在Series格式数据中。
一个大坑
上面这个数据是我目前开发项目中截取了几个值,原本的数据是一个excel表格(几万行),用pandas取出,格式为DataFrame格式,想取出DataFrame中取出一列数据(数据格式str,上面这个例子),原本是想把这一组数据找出带有‘-B’的数据,去掉‘-B’及其后面的字符,除了遍历也没有找到快捷的方法。
截取原始数据:
data = ['TMJT20012278',
'TMJT20012278',
'TMJT20012278-B1',
'TMJT20012278-B2',
'TMJT20012764',
'ZJJT20011910-B1',
'ZJJT20011910-B2'] # 这里只能先截取一段了,原始数据是从DataFrame中的一列,上万行
cba = pandas.Series(data=data)
for r in cba.index:
if cba[r].find("-B") >= 0:
cba[r] = cba[r].partition('-B')[0]
print(cba[r])
[output]
SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame
出错了,出错的原因就指向 cba[r] = cba[r].partition(’-B’)[0] 这行,说我试图设置来自于 DataFrame的片,什么原因呀?我原始数据是来自于DataFrame不错,但是我已经使用:data = self.all_data.loc[:, ‘订单号’] 取出来了。最终也没搞明白,为何会这样报错,我把这个问题归结为,修改元素方法的问题,Series 修改元素有很多方式,除了上面的方法,还有一个s.values[index] = xxx,同样的方式,把上面的代码修改为:
data = ['TMJT20012278',
'TMJT20012278',
'TMJT20012278-B1',
'TMJT20012278-B2',
'TMJT20012764',
'ZJJT20011910-B1',
'ZJJT20011910-B2'] # 这里只能先截取一段了,原始数据是从DataFrame中的一列,上万行
cba = pandas.Series(data=data)
for r in cba.index:
if cba[r].find("-B") >= 0:
cba.values[r] = cba[r].partition('-B')[0] # 用values修改不会报错!
print(cba[r])
[output]
'TMJT20012278',
'TMJT20012278',
'TMJT20012278-B1',
'TMJT20012278-B2',
'TMJT20012764',
'ZJJT20011910-B1',
'ZJJT20011910-B2'
顺利通过!
至于报错的最终原因,只能说好像是修改数据方法的问题,因为直接复制我上面的代码去测试,不会报出我那个错误,但是放到我真实的开发项目中,因为data是从一个DataFrame中取出的一列,虽然是Series格式了,是不是还带有一些DataFrame的属性,Series重新给元素赋值的方法是覆numpy和DataFrame的,而data是DataFrame身上割下来的,是不是还恋恋不舍仍然认为自己是DataFrame,就只能用values来重新赋值?哈哈