利用python进行数据分析之数据规整化(二)

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'

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容