Pandas.Series 笔记以及遇到的坑

官方详细介绍

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来重新赋值?哈哈

原创文章 12 获赞 20 访问量 1472

猜你喜欢

转载自blog.csdn.net/wuwei_201/article/details/104991469