7.3 数据转换
还有一个重要操作就是 过滤、清理、以及其他的转换工作。
7.3.1 移除重复数据
DataFrame有时候会出现重复的行:
In [27]: data=DataFrame({'k1':['one']*3+['two']*4,'k2':[1,1,2,3,3,4,4]})
In [28]: data
Out[28]:
k1 k2
0 one 1
1 one 1
2 one 2
3 two 3
4 two 3
5 two 4
6 two 4
DataFrame的duplicated方法会返回一个布尔型的Series:
In [29]: data.duplicated()
Out[29]:
0 False
1 True
2 False
3 False
4 True
5 False
6 True
dtype: bool
我们使用drop_duplicates()方法,用于移除重复行的DataFrame:
In [31]: data.drop_duplicates()
Out[31]:
k1 k2
0 one 1
2 one 2
3 two 3
5 two 4
In [32]: data['v1']=range(7)
In [33]: data
Out[33]:
k1 k2 v1
0 one 1 0
1 one 1 1
2 one 2 2
3 two 3 3
4 two 3 4
5 two 4 5
6 two 4 6
我们还可以对列进行指定去除重复值,
In [35]: data.drop_duplicates(['k1'])
Out[35]:
k1 k2 v1
0 one 1 0
3 two 3 3
In [36]: data.drop_duplicates(['k1','k2'])
Out[36]:
k1 k2 v1
0 one 1 0
2 one 2 2
3 two 3 3
5 two 4 5
duplicated和drop_duplicates 默认保留的的是第一个出现的值的组合,传入的take_last=True就可以保留最后一个。
In [37]: data.drop_duplicates(['k1','k2'],take_last=True)
__main__:1: FutureWarning: the take_last=True keyword is deprecated, use keep='last' instead
Out[37]:
k1 k2 v1
1 one 1 1
2 one 2 2
4 two 3 4
6 two 4 6
7.3.2 利用函数或映射进行数据转换
有时候我们需要给数据里面添加一列。可能希望根据数组、Series、DataFrame列中的值来实现转换工作。
In [2]: import numpy as np
...: import pandas as pd
...: from pandas import Series,DataFrame
...:
In [3]: data = DataFrame({'food':['bacon','pulled pork','bacon','Pastrami','corned beef','Bacon','pastrami',
...: 'honey ham','nova lox'],'ounces':[4,3,12,6,7.5,8,3,5,6]})
In [4]: data
Out[4]:
food ounces
0 bacon 4.0
1 pulled pork 3.0
2 bacon 12.0
3 Pastrami 6.0
4 corned beef 7.5
5 Bacon 8.0
6 pastrami 3.0
7 honey ham 5.0
8 nova lox 6.0
我们想添加这一列映射,Series的map方法可接受一个函数或者含有映射关系的字典对象。
仔细观察数据,我们发现,有些单词的字母大写了,需要进行大小写转换,否则无法添映射。
In [5]: meat_to_animal = {
...: 'bacon':'pig',
...: 'pulled pork':'pig',
...: 'pastrami':'cow',
...: 'corned beef':'cow',
...: 'honey ham':'pig',
...: 'nova lox':'salmon'
...: }
In [8]: data['animal']=data['food'].map(str.lower).map(meat_to_animal)
In [9]: data
Out[9]:
food ounces animal
0 bacon 4.0 pig
1 pulled pork 3.0 pig
2 bacon 12.0 pig
3 Pastrami 6.0 cow
4 corned beef 7.5 cow
5 Bacon 8.0 pig
6 pastrami 3.0 cow
7 honey ham 5.0 pig
8 nova lox 6.0 salmon
In [10]: data['food'].map(str.lower)
Out[10]:
0 bacon
1 pulled pork
2 bacon
3 pastrami
4 corned beef
5 bacon
6 pastrami
7 honey ham
8 nova lox
Name: food, dtype: object
或者我们可以这样做:
In [11]: data['food'].map(lambda x:meat_to_animal[x.lower()])
Out[11]:
0 pig
1 pig
2 pig
3 cow
4 cow
5 pig
6 cow
7 pig
8 salmon
Name: food, dtype: object
In [12]: lambda x:meat_to_animal[x.lower()]
Out[12]: >
彩蛋:关于lambda函数的复习
在python中,对匿名函数提供了有限支持。还是以map()函数为例,计算 f(x)=x2 时,除了定义一个f(x)的函数外,还可以直接传入匿名函数:
>>> map(lambda x:x*x,[1,2,3,4,5,6,7,8,9])
[1, 4, 9, 16, 25, 36, 49, 64, 81]
lambda x:x*x
等价于:
def f(x):
return x*x
关键字lambda表示匿名参数,冒号前面的x表示函数参数。
7.3.3 替换值
利用fillna的方法填充缺失数据可以看做替换的一种特殊情况。
replace和map都可以用于修改对象的子集。实际上replace简单、灵活。
In [13]: data=Series([1.,-999.,2.,-999.,-1000.,3.])
In [14]: data
Out[14]:
0 1.0
1 -999.0
2 2.0
3 -999.0
4 -1000.0
5 3.0
dtype: float64
#-999替换为缺失值
In [15]: data.replace(-999,np.nan)
Out[15]:
0 1.0
1 NaN
2 2.0
3 NaN
4 -1000.0
5 3.0
dtype: float64
#传入由替换值组成的列表以及一个缺失值
In [16]: data.replace([-999,-1000],np.nan)
Out[16]:
0 1.0
1 NaN
2 2.0
3 NaN
4 NaN
5 3.0
dtype: float64
In [17]: data.replace([-999,-1000],[np.nan,0])
Out[17]:
0 1.0
1 NaN
2 2.0
3 NaN
4 0.0
5 3.0
dtype: float64
#也可以传入字典
In [18]: data.replace({-999:np.nan,-1000:0})
Out[18]:
0 1.0
1 NaN
2 2.0
3 NaN
4 0.0
5 3.0
dtype: float64
7.3.4 重命名轴索引
轴标签可以通过函数或映射的关系进行转换,得到一个新对象。为了不必新建一个数据结构,轴可以修改。
In [19]: data = DataFrame(np.arange(12).reshape((3,4)),index = ['Ohio','Colorado','New York'],
...: columns = ['one','two','three','four'])
In [20]: data
Out[20]:
one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
New York 8 9 10 11
#和Series相同,轴标签也有一个map方法:
In [21]: data.index.map(str.upper)
Out[21]: array(['OHIO', 'COLORADO', 'NEW YORK'], dtype=object)
#赋值给index,对DataFrame进行修改
In [22]: data.index=data.index.map(str.upper)
In [23]: data
Out[23]:
one two three four
OHIO 0 1 2 3
COLORADO 4 5 6 7
NEW YORK 8 9 10 11
#创建数据集的转行版
In [24]: data.rename(index=str.title,columns=str.upper)
Out[24]:
ONE TWO THREE FOUR
Ohio 0 1 2 3
Colorado 4 5 6 7
New York 8 9 10 11
In [25]: index=str.title
In [26]: index
Out[26]:
#rename可以结合字典对象实现部分轴标签的更新,
In [27]: data.rename(index={'OHIO':'INDIANA'},columns={'three':'peekaboo'})
Out[27]:
one two peekaboo four
INDIANA 0 1 2 3
COLORADO 4 5 6 7
NEW YORK 8 9 10 11
rename可以实现:复制DataFrame并对其进行索引和列标签进行赋值。对希望修改的数据集,传入参数inplace=True 即可。
#总是返回DataFrame的引用
In [28]: _=data.rename(index={'OHIO':'INDIANA'},inplace=True)
In [29]: data
Out[29]:
one two three four
INDIANA 0 1 2 3
COLORADO 4 5 6 7
NEW YORK 8 9 10 11
In [30]: _
Out[30]:
one two three four
INDIANA 0 1 2 3
COLORADO 4 5 6 7
NEW YORK 8 9 10 11
7.3.5 离散化和面元划分
为了便于分析,离散化的数据常常会被离散化拆分为“面元(bin)”。
In [31]: ages = [20,22,25,27,21,23,37,31,61,45,41,32]
把数据拆分为(18,25)(25,35)(35,60)(60,100)这几各面元,可以使用pandas的cut函数,
In [32]: bins=[18,25,35,60,100]
In [33]: cats=pd.cut(ages,bins)
#返回了一个特殊的Categories 对象,看做是一组表示面元名称的字符串。
In [34]: cats
Out[34]:
[(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], ..., (25, 35], (60, 100], (35, 60], (35, 60], (25, 35]]
Length: 12
Categories (4, object): [(18, 25] < (25, 35] < (35, 60] < (60, 100]]
In [37]: pd.value_counts(cats)
Out[37]:
(18, 25] 5
(35, 60] 3
(25, 35] 3
(60, 100] 1
dtype: int64
#可以通过right=Flase来进行修改区间的开端和闭端
In [39]: cats=pd.cut(ages,bins,right=False)
In [40]: cats
Out[40]:
[[18, 25), [18, 25), [25, 35), [25, 35), [18, 25), ..., [25, 35), [60, 100), [35, 60), [35, 60), [25, 35)]
Length: 12
Categories (4, object): [[18, 25) < [25, 35) < [35, 60) < [60, 100)]
#自己设置面元名称,将labels选项设置为一个列表或数组
In [41]: group_names=['Youth','YoungAdult','MidddleAged','Senior']
In [42]: pd.cut(ages,bins,labels=group_names)
Out[42]:
[Youth, Youth, Youth, YoungAdult, Youth, ..., YoungAdult, Senior, MidddleAged, MidddleAged, YoungAdult]
Length: 12
Categories (4, object): [Youth < YoungAdult < MidddleAged < Senior]
#如果cut传入的面元的数量没有确切的边界,则会根据数据的最小值和最大值计算等面元。
In [43]: data=np.random.rand(20)
In [44]: data
Out[44]:
array([ 0.18052819, 0.30816514, 0.12574293, ..., 0.69175506,
0.46870553, 0.56315958])
#将数据均匀的分布为4组,小数精度保留3位
In [45]: pd.cut(data,4,precision=3)
Out[45]:
[(0.0834, 0.304], (0.304, 0.523], (0.0834, 0.304], (0.523, 0.742], (0.304, 0.523], ..., (0.0834, 0.304], (0.304, 0.523], (0.523, 0.742], (0.304, 0.523], (0.523, 0.742]]
Length: 20
Categories (4, object): [(0.0834, 0.304] < (0.304, 0.523] < (0.523, 0.742] < (0.742, 0.961]]
In [46]: pd.cut(data,4,precision=2)
Out[46]:
[(0.083, 0.3], (0.3, 0.52], (0.083, 0.3], (0.52, 0.74], (0.3, 0.52], ..., (0.083, 0.3], (0.3, 0.52], (0.52, 0.74], (0.3, 0.52], (0.52, 0.74]]
Length: 20
Categories (4, object): [(0.083, 0.3] < (0.3, 0.52] < (0.52, 0.74] < (0.74, 0.96]]
#qcut使用的是样本的分位数,可以得到基本大小相等的面元
#正态分布
In [47]: data=np.random.randn(100)
#按四分位数进行切割
In [48]: cats=pd.cut(data,4)
In [49]: cats
Out[49]:
[(-0.824, 0.467], (-0.824, 0.467], (-0.824, 0.467], (-2.121, -0.824], (-0.824, 0.467], ..., (-0.824, 0.467], (-0.824, 0.467], (-0.824, 0.467], (-2.121, -0.824], (-2.121, -0.824]]
Length: 100
Categories (4, object): [(-2.121, -0.824] < (-0.824, 0.467] < (0.467, 1.759] < (1.759, 3.0507]]
In [50]: cats=pd.cut(data,4,precision=2)
In [51]: cats
Out[51]:
[(-0.82, 0.47], (-0.82, 0.47], (-0.82, 0.47], (-2.12, -0.82], (-0.82, 0.47], ..., (-0.82, 0.47], (-0.82, 0.47], (-0.82, 0.47], (-2.12, -0.82], (-2.12, -0.82]]
Length: 100
Categories (4, object): [(-2.12, -0.82] < (-0.82, 0.47] < (0.47, 1.76] < (1.76, 3.051]]
In [53]: pd.value_counts(cats)
Out[53]:
(-0.82, 0.47] 50
(0.47, 1.76] 24
(-2.12, -0.82] 21
(1.76, 3.051] 5
dtype: int64
In [54]: pd.qcut(data,[0,0.1,0.5,0.9,1.])
Out[54]:
[(-1.239, -0.171], (-1.239, -0.171], (-0.171, 1.399], (-1.239, -0.171], (-0.171, 1.399], ..., (-1.239, -0.171], (-0.171, 1.399], (-1.239, -0.171], [-2.116, -1.239], (-1.239, -0.171]]
Length: 100
Categories (4, object): [[-2.116, -1.239] < (-1.239, -0.171] < (-0.171, 1.399] < (1.399, 3.0507]]
#可以设置自定义的分位数
In [55]: df=pd.qcut(data,[0,0.1,0.5,0.9,1.])
In [56]: pd.value_counts(df)
Out[56]:
(-0.171, 1.399] 40
(-1.239, -0.171] 40
(1.399, 3.0507] 10
[-2.116, -1.239] 10
dtype: int64
7.3.6 检测和过滤异常值
异常值的过滤或变换运算在很大程度上就是数组运算。
In [58]: np.random.seed(12345)
In [59]: data=DataFrame(np.random.randn(1000,4))
In [60]: data
Out[60]:
0 1 2 3
0 -0.204708 0.478943 -0.519439 -0.555730
1 1.965781 1.393406 0.092908 0.281746
2 0.769023 1.246435 1.007189 -1.296221
3 0.274992 0.228913 1.352917 0.886429
4 -2.001637 -0.371843 1.669025 -0.438570
.. ... ... ... ...
995 1.089085 0.251232 -1.451985 1.653126
996 -0.478509 -0.010663 -1.060881 -1.502870
997 -1.946267 1.013592 0.037333 0.133304
998 -1.293122 -0.322542 -0.782960 -0.303340
999 0.089987 0.292291 1.177706 0.882755
[1000 rows x 4 columns]
In [61]: data.describe()
Out[61]:
0 1 2 3
count 1000.000000 1000.000000 1000.000000 1000.000000
mean -0.067684 0.067924 0.025598 -0.002298
std 0.998035 0.992106 1.006835 0.996794
min -3.428254 -3.548824 -3.184377 -3.745356
25% -0.774890 -0.591841 -0.641675 -0.644144
50% -0.116401 0.101143 0.002073 -0.013611
75% 0.616366 0.780282 0.680391 0.654328
max 3.366626 2.653656 3.260383 3.927528
#找出某列中绝对值大小超过3的值
In [62]: col=data[3]
In [63]: col[np.abs(col)>3]
Out[63]:
97 3.927528
305 -3.399312
400 -3.745356
Name: 3, dtype: float64
#找出数据中全部绝对值大小超过3的值,使用any方法
In [65]: data[(np.abs(data)>3).any(1)]
Out[65]:
0 1 2 3
5 -0.539741 0.476985 3.248944 -1.021228
97 -0.774363 0.552936 0.106061 3.927528
102 -0.655054 -0.565230 3.176873 0.959533
305 -2.315555 0.457246 -0.025907 -3.399312
324 0.050188 1.951312 3.260383 0.963301
400 0.146326 0.508391 -0.196713 -3.745356
499 -0.293333 -0.242459 -3.056990 1.918403
523 -3.428254 -0.296336 -0.439938 -0.867165
586 0.275144 1.179227 -3.184377 1.369891
808 -0.362528 -3.548824 1.553205 -2.186301
900 3.366626 -2.372214 0.851010 1.332846
#可以将置限制在(-3,3)的区间内
#np.sign 这个ufunc返回的是一个由1和-1组成的数组,表示原始值的符号
In [66]: data[(np.abs(data)>3)]=np.sign(data)*3
In [67]: data.describe()
Out[67]:
0 1 2 3
count 1000.000000 1000.000000 1000.000000 1000.000000
mean -0.067623 0.068473 0.025153 -0.002081
std 0.995485 0.990253 1.003977 0.989736
min -3.000000 -3.000000 -3.000000 -3.000000
25% -0.774890 -0.591841 -0.641675 -0.644144
50% -0.116401 0.101143 0.002073 -0.013611
75% 0.616366 0.780282 0.680391 0.654328
max 3.000000 2.653656 3.000000 3.000000
7.3.7 排列(permutation)和随机采样
利用numpy.random.permutation可以对Series和DataFrame进行排列
通过需要排列的轴的长度调用permutation,会产生一个表示新顺序的整数数组。
In [68]: df=DataFrame(np.arange(5*4).reshape(5,4))
In [69]: sampler=(np.random.permutation(5))
In [70]: df
Out[70]:
0 1 2 3
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
3 12 13 14 15
4 16 17 18 19
In [71]: sampler
Out[71]: array([1, 0, 2, 3, 4])
#在基于ix的索引操作或take函数中使用该数组了
In [73]: df.take(sampler)
Out[73]:
0 1 2 3
1 4 5 6 7
0 0 1 2 3
2 8 9 10 11
3 12 13 14 15
4 16 17 18 19
#可以看到,直接这样切片,报错了
In [75]: df.take(np.random.permutation(len(df)[:3]))
Traceback (most recent call last):
File "", line 1, in
df.take(np.random.permutation(len(df)[:3]))
TypeError: 'int' object has no attribute '__getitem__'
In [76]: len(df)
Out[76]: 5
In [77]: len(df)[:3]
Traceback (most recent call last):
File "", line 1, in
len(df)[:3]
TypeError: 'int' object has no attribute '__getitem__'
#从permutation返回的数组中切片出前k个元素,其中k为期望的子集大小。
In [85]: df.take(np.random.permutation(np.arange(len(df))[:3]))
Out[85]:
0 1 2 3
1 4 5 6 7
0 0 1 2 3
2 8 9 10 11
In [87]: np.arange(len(df))[:3]
Out[87]: array([0, 1, 2])
#In [89]: bag=np.array([5,7,-1,6,4])
#要通过替换的方式生产样本,最快的方式是通过np.random.randint得到一组随机整数
In [91]: sampler=np.random.randint(0,len(bag),size=10)
In [92]: sampler
Out[92]: array([4, 4, 4, 2, 2, 2, 0, 3, 0, 4])
In [95]: sampler=np.random.randint(0,5,size=10)
In [96]: sampler
Out[96]: array([1, 2, 0, 4, 4, 4, 3, 4, 2, 2])
In [97]: draws=bag.take(sampler)
In [98]: draws
Out[98]: array([ 7, -1, 5, 4, 4, 4, 6, 4, -1, -1])
7.3.8 计算指标/哑变量
另一种常用于统计建模或机器学习的转换方式:将分类变量(categorical variable)转换为“哑变量矩阵(dummy matrix)”或“指标矩阵(indicator matrix)”。
若DataFrame的某一列含有k不同的值,则可以派生出一个k列矩阵或DataFrame(其值全为0或1)。
pandas中的get_dummies函数可以实现上面的功能。
In [15]: mnames=['movie_id','title','genres']
In [16]: movies=pd.read_table('F:\pydata-book-master\ch02\movielens\movies.dat',sep='::',header=None,names=mnames)
__main__:1: ParserWarning: Falling back to the 'python' engine because the 'c' engine does not support regex separators (separators > 1 char and different from '\s+' are interpreted as regex); you can avoid this warning by specifying engine='python'.
#观察一下数据最前面的10行
In [17]: movies[:10]
Out[17]:
movie_id title genres
0 1 Toy Story (1995) Animation|Children's|Comedy
1 2 Jumanji (1995) Adventure|Children's|Fantasy
2 3 Grumpier Old Men (1995) Comedy|Romance
3 4 Waiting to Exhale (1995) Comedy|Drama
4 5 Father of the Bride Part II (1995) Comedy
5 6 Heat (1995) Action|Crime|Thriller
6 7 Sabrina (1995) Comedy|Romance
7 8 Tom and Huck (1995) Adventure|Children's
8 9 Sudden Death (1995) Action
9 10 GoldenEye (1995) Action|Adventure|Thriller
[3873 rows x 3 columns]
#观察一下数据最后的5行
In [21]: movies[-5:]
Out[21]:
movie_id title genres
3878 3948 Meet the Parents (2000) Comedy
3879 3949 Requiem for a Dream (2000) Drama
3880 3950 Tigerland (2000) Drama
3881 3951 Two Family House (2000) Drama
3882 3952 Contender, The (2000) Drama|Thriller
#要为每个genre添加指标变量
In [22]: genre_iter=(set(x.split('|')) for x in movies.genres)
#从数据中抽取出不同的genre值,使用set.union,并排序
In [23]: genres=sorted(set.union(*genre_iter))
#从一个全零的DataFrame开始构建指标DataFrame
In [24]: dummies=DataFrame(np.zeros((len(movies),len(genres))),columns=genres)
In [25]: len(movies)
Out[25]: 3883
In [26]: len(genres)
Out[26]: 18
#迭代每一部电影并将dummies设为1
In [27]: for i,gen in enumerate(movies.genres):
...: dummies.ix[i,gen.split('|')]=1
...:
#将dummies与movies两个数据集合并起来
In [28]: movies_windic=movies.join(dummies.add_prefix('Genre_'))
In [29]: movies_windic.ix[0]
Out[29]:
movie_id 1
title Toy Story (1995)
genres Animation|Children's|Comedy
Genre_Action 0
Genre_Adventure 0
Genre_Animation 1
Genre_Children's 1
Genre_Comedy 1
Genre_Crime 0
Genre_Documentary 0
Genre_Drama 0
Genre_Fantasy 0
Genre_Film-Noir 0
Genre_Horror 0
Genre_Musical 0
Genre_Mystery 0
Genre_Romance 0
Genre_Sci-Fi 0
Genre_Thriller 0
Genre_War 0
Genre_Western 0
Name: 0, dtype: object
In [30]: movies_windic.head()
Out[30]:
movie_id title genres \
0 1 Toy Story (1995) Animation|Children's|Comedy
1 2 Jumanji (1995) Adventure|Children's|Fantasy
2 3 Grumpier Old Men (1995) Comedy|Romance
3 4 Waiting to Exhale (1995) Comedy|Drama
4 5 Father of the Bride Part II (1995) Comedy
Genre_Action Genre_Adventure Genre_Animation Genre_Children's \
0 0.0 0.0 1.0 1.0
1 0.0 1.0 0.0 1.0
2 0.0 0.0 0.0 0.0
3 0.0 0.0 0.0 0.0
4 0.0 0.0 0.0 0.0
Genre_Comedy Genre_Crime Genre_Documentary ... Genre_Fantasy \
0 1.0 0.0 0.0 ... 0.0
1 0.0 0.0 0.0 ... 1.0
2 1.0 0.0 0.0 ... 0.0
3 1.0 0.0 0.0 ... 0.0
4 1.0 0.0 0.0 ... 0.0
Genre_Film-Noir Genre_Horror Genre_Musical Genre_Mystery Genre_Romance \
0 0.0 0.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0 0.0
2 0.0 0.0 0.0 0.0 1.0
3 0.0 0.0 0.0 0.0 0.0
4 0.0 0.0 0.0 0.0 0.0
Genre_Sci-Fi Genre_Thriller Genre_War Genre_Western
0 0.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0
2 0.0 0.0 0.0 0.0
3 0.0 0.0 0.0 0.0
4 0.0 0.0 0.0 0.0
[5 rows x 21 columns]
对于很大的数据,上面这种方式构建的多成员的指标变量会变得很慢,需要编写一个利用DataFrame内部机制的更低的函数才行。
解决办法:结合get_dummies和例如cut的离散化函数
In [31]: values=np.random.rand(10)
In [32]: values
Out[32]:
array([ 0.06125988, 0.71829361, 0.71451639, 0.31675263, 0.43739154,
0.48855471, 0.87401469, 0.65884824, 0.88474031, 0.57315729])
In [33]: bins=[0,0.2,0.4,0.6,0.8,1]
In [34]: pd.get_dummies(pd.cut(values,bins))
Out[34]:
(0, 0.2] (0.2, 0.4] (0.4, 0.6] (0.6, 0.8] (0.8, 1]
0 1 0 0 0 0
1 0 0 0 1 0
2 0 0 0 1 0
3 0 1 0 0 0
4 0 0 1 0 0
5 0 0 1 0 0
6 0 0 0 0 1
7 0 0 0 1 0
8 0 0 0 0 1
9 0 0 1 0 0
7.4 字符串操作
python对于大部分文本运算都直接做成了字符串的内置方法,对于更为复杂的模式匹配和文本操作,就需要正则表达式了。
7.4.1 字符串对象方法
对于大部分字符串处理应用而言,内置的字符串方法就可以满足要求。
如,以逗号分隔的字符串可以用split拆分成数段:
In [42]: val='a, b, guido'
In [43]: val.split(',')
Out[43]: ['a', ' b', ' guido']
#split常常结合strip(用于修剪空白符(包括换行符))一起使用
In [44]: pieces=[x.strip() for x in val.split(',')]
In [45]: pieces
Out[45]: ['a', 'b', 'guido']
#利用加法,可以将这些子字符串以双冒号分隔符的形式连接起来
In [46]: first,second,third=pieces
In [48]: first + '::' + second + '::' +third
Out[48]: 'a::b::guido'
#我们还可以向字符串"::" 的join方法传入一个列表或元组
In [49]: '::'.join(pieces)
Out[49]: 'a::b::guido'
#检测子串的利用in关键字
In [50]: 'guido' in val
Out[50]: True
In [51]: val.index(',')
Out[51]: 1
In [52]: val.find(':')
Out[52]: -1
#index和find有区别的,找不到字符串就会报错
In [53]: val.index(':')
Traceback (most recent call last):
File "", line 1, in
val.index(':')
ValueError: substring not found
#指定字符串出现次数
In [54]: val.count(',')
Out[54]: 2
#replace将指定模式替换为另一个模式
In [55]: val.replace(',','::')
Out[55]: 'a:: b:: guido'
In [56]: val.replace(',', '')
Out[56]: 'a b guido'