pandas 数据清洗和预处理

本篇博客主要介绍了pandas在数据清洗和预处理中的常用方法,包括判断和处理缺失值(如isnull(), dropna(), fillna()),移除重复值,数据转换(如映射、函数转换、替换值、重命名轴索引),字符串操作(如正则表达式、矢量化字符串函数)等。详细讲述了各种方法的参数和用法。" 106074303,9389184,使用 Docker 快速安装 MongoDB,"['Docker', '数据库', 'NoSQL', 'MongoDB']
摘要由CSDN通过智能技术生成

pandas 笔记010

十、数据清洗和预处理

1. 处理缺失数据

处理缺失数据思路:

  • 1.判断是否存在缺失值 isnull()

  • 2.丢弃缺失数据 dropna()

  • 3.填充缺失数据 fillna()

b1 = pd.DataFrame([np.random.randn(3), [1., 2., np.nan],
                    [np.nan, 4., np.nan], [1., 2., 3.],[np.nan,np.nan,np.nan]])
b1
    0			1			2
0	0.907143	-1.930521	-0.936026
1	1.000000	2.000000	NaN
2	NaN			4.000000	NaN
3	1.000000	2.000000	3.000000
4	NaN			NaN			NaN
1.1 判断是否存在缺失值 isnull()
b1.isnull()  #返回布尔值,为缺失值返回True,否则返回False
	0		1		2
0	False	False	False
1	False	False	True
2	True	False	True
3	False	False	False
4	True	True	True
1.2 丢弃缺失数据 dropna()
b1.dropna()   #默认会丢弃存在nan的整行(axis=0)
	0		  1			  2
0	0.27505	  2.666388	  -1.282808
3	1.00000	  2.000000	  3.000000

丢弃存在nan的整列

b1.dropna(axis=1)    #丢弃存在nan的整列(这里每列都有NAN,所以返回的是行索引)
0
1
2
3
4

参数how='all' :

只删除整行都是NAN的行(默认为行axis=0)或整列都是NAN的列(axis=1),并且会改变原DataFrame索引

b11 = pd.DataFrame([[2.5,6,np.nan], [1., 2., np.nan],
                    [np.nan, np.nan , np.nan], [1., 2., np.nan],[np.nan,np.nan,np.nan]])
print(b11)
print("="*30)
print(b11.dropna(how="all"))   # 删除整行NAN
print("="*30)
print(b11.dropna(how="all",axis=1))    # 删除整列NAN
     0    1   2
0  2.5  6.0 NaN
1  1.0  2.0 NaN
2  NaN  NaN NaN
3  1.0  2.0 NaN
4  NaN  NaN NaN
==============================
     0    1   2
0  2.5  6.0 NaN
1  1.0  2.0 NaN
3  1.0  2.0 NaN
==============================
     0    1
0  2.5  6.0
1  1.0  2.0
2  NaN  NaN
3  1.0  2.0
4  NaN  NaN
b2 = pd.DataFrame(np.random.randn(7,3))
b2
	0			1			2
0	0.234058	1.636350	-0.761125
1	1.721174	0.139274	-0.918762
2	0.722270	1.349294	-0.011783
3	-0.288692	1.178598	-1.491171
4	0.899841	-1.209080	-1.948781
5	1.692673	0.416204	-0.271325
6	0.814284	-0.035392	-0.360542
b2.iloc[:4,1] = np.nan  #iloc位置索引,第一个参数为行,第二个参数为列,这里表示将前四行第二列变为NAN
b2.iloc[:2,2] = np.nan   #表示将前2行第3列变为NAN
b2
	0				1			2
0	0.234058		NaN			NaN
1	1.721174		NaN			NaN
2	0.722270		NaN			-0.011783
3	-0.288692		NaN			-1.491171
4	0.899841		-1.209080	-1.948781
5	1.692673		0.416204	-0.271325
6	0.814284		-0.035392	-0.360542

参数thresh : dropna( thresh = n )表示一行数据如果剔除nan后这行数据剩余的数据的数量大于或等于n时,就返回这行数据,否则不返回。

b2.dropna(thresh=2)   # 第0,1行删除NAN后只剩1个数据,不返回,其他行如果剔除NAN的数据数量大于或等于2,返回整行数据
	0				1			2
2	0.722270		NaN			-0.011783
3	-0.288692		NaN			-1.491171
4	0.899841		-1.209080	-1.948781
5	1.692673		0.416204	-0.271325
6	0.814284		-0.035392	-0.360542
b2.dropna(thresh=3)   #剔除NAN后返回数据大于3的这行数据
	0			1			2
4	0.899841	-1.209080	-1.948781
5	1.692673	0.416204	-0.271325
6	0.814284	-0.035392	-0.360542
1.3 填充缺失值 fillna()
b2    #改变后的b2值如下
	0			1			2
0	0.234058	NaN			NaN
1	1.721174	NaN			NaN
2	0.722270	NaN			-0.011783
3	-0.288692	NaN			-1.491171
4	0.899841	-1.209080	-1.948781
5	1.692673	0.416204	-0.271325
6	0.814284	-0.035392	-0.360542

填充NAN值为10

b2.fillna(10)    #注意填充的数据类型不需要和原有数据类型一致
	0			1			2
0	0.234058	10.000000	10.000000
1	1.721174	10.000000	10.000000
2	0.722270	10.000000	-0.011783
3	-0.288692	10.000000	-1.491171
4	0.899841	-1.209080	-1.948781
5	1.692673	0.416204	-0.271325
6	0.814284	-0.035392	-0.360542
1.3.1 精确填充

使用字典

返回一个新的DataFrame对象,不会改变原来的b2,默认参数inplace=False,如果inplace=True就会改变原b2

b2.fillna({1:6,2:5})  #表示索引为1的列的nan替换为6,索引为2的nan替换为5,默认参数inplace=False
	0			1			2
0	0.234058	6.000000	5.000000
1	1.721174	6.000000	5.000000
2	0.722270	6.000000	-0.011783
3	-0.288692	6.000000	-1.491171
4	0.899841	-1.209080	-1.948781
5	1.692673	0.416204	-0.271325
6	0.814284	-0.035392	-0.360542
1.3.2 参数inplace=True
b2.fillna({1:6,2:5},inplace=True)  #inplace=True不返回新的对象,会改变原b2
b2
	0			1			2
0	0.234058	6.000000	5.000000
1	1.721174	6.000000	5.000000
2	0.722270	6.000000	-0.011783
3	-0.288692	6.000000	-1.491171
4	0.899841	-1.209080	-1.948781
5	1.692673	0.416204	-0.271325
6	0.814284	-0.035392	-0.360542
1.3.3 参数method=‘ffill’

将每一列第一个NAN的同一列上一行的数填充到该列的NAN中。如果该列全为NAN则不会变化。

q1 = pd.DataFrame(np.random.randn(6,3))
q1.iloc[3:,0] = np.nan
q1.iloc[4:,2] = np.nan
q1
	0			1			2
0	-0.877885	0.551821	-2.350924
1	1.812377	-0.106464	-0.135449
2	1.905657	-1.854603	0.477252
3	NaN			-0.193901	0.350264
4	NaN			-0.766737	NaN
5	NaN			1.163864	NaN

将NAN值填充为其同一列上一行的数1.905657,0.350264

q1.fillna(method='ffill')  #返回新对象,不改变q1
	0			1			2
0	-0.877885	0.551821	-2.350924
1	1.812377	-0.106464	-0.135449
2	1.905657	-1.854603	0.477252
3	1.905657	-0.193901	0.350264
4	1.905657	-0.766737	0.350264
5	1.905657	1.163864	0.350264
1.3.4 参数limit

表示要限制每列填充NAN的个数.

limit=2限制最多填两个,第5行的NAN 为第0列的第三个NAN,被限制填充。

q1.fillna(method='ffill',limit=2)   
	0			1			2
0	-0.877885	0.551821	-2.350924
1	1.812377	-0.106464	-0.135449
2	1.905657	-1.854603	0.477252
3	1.905657	-0.193901	0.350264
4	1.905657	-0.766737	0.350264
5	NaN			1.163864	0.350264
2. 数据转换
2.1 移除重复值
da = pd.DataFrame({'k1':['one','two']*3+['two'],
                   'k2':[1,2,1,1,3,2,3]})
da
    k1		k2
0	one		1
1	two		2
2	one		1
3	two		1
4	one		3
5	two		2
6	two		3
2.1.1 duplicated():检查是否为重复行

duplicated()返回布尔型Series表示每行是否为重复行。
从0索引开始到最后,每行和前面出现过的行比较,如果重复返回True,不重复返回False

da.duplicated()   #不改变原DataFrame
0    False
1    False
2     True
3    False
4    False
5     True
6    False
dtype: bool
2.1.2 drop_duplicates()过滤重复行

默认判断全部列,也可指定列判断。

从0索引开始到最后,每行和前面出现过的行比较,如果重复则删除(不改变原DataFrame),如果重复默认保留前面那一行

da.drop_duplicates()   
    k1		k2
0	one		1
1	two		2
3	two		1
4	one		3
6	two		3

指定k2列过滤重复行(不改变原DataFrame),不用管其他列是否重复。

da.drop_duplicates('k2')    #如果重复默认保留前面那一行
	k1		k2
0	one		1
1	two		2
4	one		3
2.1.3 keep=‘last’ (如果重复则保留后面那一行)
da.drop_duplicates(keep='last')   
    k1		k2
2	one		1
3	two		1
4	one		3
5	two		2
6	two		3
da.drop_duplicates('k2',keep='last') 
k1	k2
3	two	1
5	two	2
6	two	3
2.2 利用映射或函数转换数据
test = pd.DataFrame({'food':['apple','Tomato','mango','orange','Lemon','Apple'],
                    'price':[2,3.1,5,2.3,6,9]})
test
	food	price
0	apple	2.0
1	Tomato	3.1
2	mango	5.0
3	orange	2.3
4	Lemon	6.0
5	Apple	9.0

lower() 转换为小写

#将food这列转换为小写
low = test['food'].str.lower()
low
0     apple
1    tomato
2     mango
3    orange
4     lemon
5     apple
Name: food, dtype: object
meat = {
    'apple':'fruit',
    'tomato':'vegetable',
    'mango':'fruit',
    'orange':'fruit',
    'lemon':'fruit',
}
# map传入的函数对每行或每列进行转换
#test['class'] = test['food'].map(meat)
test['class'] = low.map(meat)
test
	ood			price		class
0	apple		2.0			fruit
1	Tomato		3.1			vegetable
2	mango		5.0			fruit
3	orange		2.3			fruit
4	Lemon		6.0			fruit
5	Apple		9.0			fruit

使用匿名函数lambda

test['class1'] = test['food'].map(lambda x:meat[x.lower()])
test
	food		price		class		class1
0	apple		2.0			fruit		fruit
1	Tomato		3.1			vegetable	vegetable
2	mango		5.0			fruit		fruit
3	orange		2.3			fruit		fruit
4	Lemon		6.0			fruit		fruit
5	Apple		9.0			fruit		fruit
2.3 替换值
2.3.1 replace()替换一个值
kt = pd.Series([2,4,5,-991,7,10000])
kt
0        2
1        4
2        5
3     -991
4        7
5    10000
dtype: int64

replace():根据值的内容进行替换 ,可以替换异常值

replace()方法返回一个新的Series对象,不会改变原Series对象

kt1 = kt.replace(-991,6)  #将异常值-991替换为6
kt1   
0        2
1        4
2        5
3        6
4        7
5    10000
dtype: int64
2.3.2 replace()方法替换多个值

使用列表替换

#替换多个值
kt2 = kt.replace([-991,10000],[np.nan,4])  # 列表替换,将-991替换为NAN,将10000替换为4
kt2
0    2.0
1    4.0
2    5.0
3    NaN
4    7.0
5    4.0
dtype: float64

使用字典替换

kt3 = kt.replace({-991:np.nan,10000:4})   # 字典替换,将-991替换为NAN,将10000替换为4
kt3
0    2.0
1    4.0
2    5.0
3    NaN
4    7.0
5    4.0
dtype: float64
2.4 重命名轴索引
lc = pd.DataFrame(np.arange(12).reshape(3,4),index=['Beijing','Shanghai','Guangzhou'],columns=['a','b','c','d'])
lc
			a	b	c	d
Beijing		0	1	2	3
Shanghai	4	5	6	7
Guangzhou	8	9	10	11

重新索引 reindex

#如果新索引和原索引不同,返回NAN,相同则返回原索引对应的值,和索引顺序无关
lc1 = lc.reindex(index=['A','B','Beijing'],columns=['c','r','a','f'])
lc1
		c	r	a	f
A		NaN	NaN	NaN	NaN
B		NaN	NaN	NaN	NaN
Beijing	2.0	NaN	0.0	NaN
#取lc行索引前四位并大写
func = lambda x:x[:4].upper()
lc.index.map(func)
Index(['BEIJ', 'SHAN', 'GUAN'], dtype='object')

改变了原DataFrame

lc.index = lc.index.map(func)
lc  #改变了原DataFrame
		a	b	c	d
BEIJ	0	1	2	3
SHAN	4	5	6	7
GUAN	8	9	10	11

rename:返回一个新的对象,不改变原索引DataFrame

lc2 = lc.rename(index=str.title,columns=str.upper)
print(lc2)
print("="*20)
print(lc)
	  A  B   C   D
Beij  0  1   2   3
Shan  4  5   6   7
Guan  8  9  10  11
====================
      a  b   c   d
BEIJ  0  1   2   3
SHAN  4  5   6   7
GUAN  8  9  10  11

rename结合字典型对象对标签进行更新(返回新对象,不改变原索引)

lc.rename(index={'BEIJ':'北京'},columns={'b':'第二'})
		a	第二	  c	  d
北京	    0	  1	  2	  3
SHAN	4	  5	  6	  7
GUAN	8 	  9	  10  11

inplace参数:默认为False,为True则改变原索引

c.rename(index={'BEIJ':'北京'},columns={'b':'第二'},inplace=True)
lc #改变了lc
		a	第二	  c	  d
北京	    0	  1	  2	  3
SHAN	4	  5	  6	  7
GUAN	8 	  9	  10  11
2.5 数据的面元划分
#面元划分
ages = [23,15,63,45,34,57,32,28,19,26,35,38]
#面元bin
bins = [15,25,35,45,55,65]  #划分为5个面元(5个阶段0,1,2,3,4)
cats = pd.cut(ages,bins)  #如果ages不在任何阶段,返回NAN(阶段为-1)
cats
[(15.0, 25.0], NaN, (55.0, 65.0], (35.0, 45.0], (25.0, 35.0], ..., (25, 35], (15, 25], (25, 35], (25, 35], (35, 45]]
Length: 12
Categories (5, interval[int64]): [(15, 25] < (25, 35] < (35, 45] < (45, 55] < (55, 65]]

查看阶段

cats.codes #查看阶段
array([ 0, -1,  4,  2,  1,  4,  1,  1,  0,  1,  1,  2], dtype=int8)

数组标签categories(默认左开右闭)

#数组标签categories(左开右闭)
cats.categories
IntervalIndex([(15, 25], (25, 35], (35, 45], (45, 55], (55, 65]],
              closed='right',
              dtype='interval[int64]')

value_counts 统计不同面元含有的个数(按数量降序排序)

#统计不同面元含有的个数(按数量降序排序)
pd.value_counts(cats)
(25, 35]    5
(15, 25]    2
(35, 45]    2
(55, 65]    2
(45, 55]    0
dtype: int64

right参数:指定哪边是开区间(默认左开右闭)

pd.cut(ages,[14,28,40,60,100],right=False)
[[14, 28), [14, 28), [60, 100), [40, 60), [28, 40), ..., [28, 40), [14, 28), [14, 28), [28, 40), [28, 40)]
Length: 12
Categories (4, interval[int64]): [[14, 28) < [28, 40) < [40, 60) < [60, 100)]

指定面元阶段的名字names参数

#指定面元阶段的名字names参数
names = ['青年','中年','近老年','迟暮']
pd.cut(ages,[14,28,40,60,100],labels=names) 
['青年', '青年', '迟暮', '近老年', '中年', ..., '青年', '青年', '青年', '中年', '中年']
Length: 12
Categories (4, object): ['青年' < '中年' < '近老年' < '迟暮']

平均分配面元

data = np.random.rand(20)
data
array([0.35262706, 0.12335161, 0.81014855, 0.2668935 , 0.32923107,
       0.42491431, 0.89782664, 0.240483  , 0.31953278, 0.89815895,
       0.98732044, 0.35656191, 0.28094352, 0.57002078, 0.88107312,
       0.55998232, 0.90544195, 0.57850912, 0.41981942, 0.67127072])
#平均分配面元
ft = pd.cut(data,5,precision=4) #第二个参数表示划分为多少个面元,第三个参数表示小数位数
ft
[(0.2961, 0.4689], (0.1225, 0.2961], (0.6417, 0.8145], (0.1225, 0.2961], (0.2961, 0.4689], ..., (0.4689, 0.6417], (0.8145, 0.9873], (0.4689, 0.6417], (0.2961, 0.4689], (0.6417, 0.8145]]
Length: 20
Categories (5, interval[float64]): [(0.1225, 0.2961] < (0.2961, 0.4689] < (0.4689, 0.6417] < (0.6417, 0.8145] < (0.8145, 0.9873]]
pd.value_counts(ft)   # 统计不同面元含有的个数(按数量降序排序)
(0.2961, 0.4689]    6
(0.8145, 0.9873]    5
(0.1225, 0.2961]    4
(0.4689, 0.6417]    3
(0.6417, 0.8145]    2
dtype: int64

qcut函数:使每个面元中的数量个数相同

#qcut函数
fdata = np.random.rand(1000)
fdata
array([6.56474038e-01, 8.69345270e-02, 1.74909770e-01, 3.94467953e-01,
       7.33962615e-03, 8.52879612e-02, 5.68239131e-01, 7.65302833e-01,
       8.26279609e-01, 4.02739183e-01, 5.10561779e-01, 1.60643562e-01,
       4.51711456e-01, 9.43778760e-01, 7.62585950e-01, 1.39137365e-01,
       1.06491544e-02, 8.14436593e-01, 7.60644931e-01, 5.58164244e-01,
       9.82935564e-03, 1.72151487e-01, 9.84280740e-01, 7.91426442e-01,
       7.38290659e-01, 6.27698507e-01, 4.63542640e-01, 1.59926081e-01,
       2.28939426e-01, 8.18511513e-01, 2.82050592e-01, 6.93174409e-01,
       2.09935727e-01, 3.03347155e-01, 2.75805874e-01, 5.18623114e-01,
       1.70286310e-01, 9.68991294e-01, 7.44635796e-02, 4.41309472e-01,
       ...............................................................])

qcut :使每个面元中的数量个数相同

fcats = pd.qcut(fdata,4)
fcats
[(0.47, 0.739], (-0.00024300000000000005, 0.225], (-0.00024300000000000005, 0.225], (0.225, 0.47], (-0.00024300000000000005, 0.225], ..., (0.47, 0.739], (0.225, 0.47], (0.739, 0.998], (0.225, 0.47], (0.225, 0.47]]
Length: 1000
Categories (4, interval[float64]): [(-0.00024300000000000005, 0.225] < (0.225, 0.47] < (0.47, 0.739] < (0.739, 0.998]]

平均分配面元中的数量个数

pd.value_counts(fcats) #平均分配面元中的数量个数
(-0.00024300000000000005, 0.225]    250
(0.225, 0.47]                       250
(0.47, 0.739]                       250
(0.739, 0.998]                      250
dtype: int64

按比例1:4:4:1分配数量到各面元

fcats1 = pd.qcut(fdata,[0,0.1,0.5,0.9,1])
fcats1
[(0.47, 0.892], (-0.00024300000000000005, 0.098], (0.098, 0.47], (0.098, 0.47], (-0.00024300000000000005, 0.098], ..., (0.47, 0.892], (0.098, 0.47], (0.47, 0.892], (0.098, 0.47], (0.098, 0.47]]
Length: 1000
Categories (4, interval[float64]): [(-0.00024300000000000005, 0.098] < (0.098, 0.47] < (0.47, 0.892] < (0.892, 0.998]]
pd.value_counts(fcats1)  #按比例1:4:4:1分配数量到各面元
(0.098, 0.47]                       400
(0.47, 0.892]                       400
(-0.00024300000000000005, 0.098]    100
(0.892, 0.998]                      100
dtype: int64
2.6 检测和过滤异常值
pu = pd.DataFrame(np.random.randn(1000,4))
pu
	0			1			2			3
0	-0.087312	-0.716446	-0.284581	-0.427966
1	-0.100517	-0.257161	-0.285024	-0.286679
2	-0.234363	2.418358	0.033771	1.123589
3	1.186212	0.457050	-0.457038	0.737496
4	0.914971	-0.462259	0.091660	-1.225298
...	...	...	...	...
995	0.625998	-0.239795	-0.076285	2.136896
996	-0.246795	0.432595	-1.239747	0.580199
997	1.135216	0.395310	-0.528132	-1.248656
998	0.190378	0.089952	0.092734	-1.197069
999	0.172124	-0.763129	1.174957	0.679519
1000 rows × 4 columns

检测绝对值有大于3的行

pu[(np.abs(pu)>3).any(1)]
	0			1			2			3
74	-3.299366	-0.017787	-0.676287	-0.306911
85	0.043003	0.606403	0.348421	-3.215305
151	0.126528	-0.412491	3.357514	0.276761
165	3.278815	-1.020282	-0.479210	-0.901612
170	3.321176	-0.724095	-0.701113	1.615443
465	1.375632	0.192247	3.133677	1.385816
479	-0.887973	-0.380403	0.088809	3.394779
480	-0.463443	-3.822245	0.068246	1.122774
580	-3.054907	-0.297027	-0.809030	1.216626
901	-0.271612	0.438777	-3.010351	-1.135718
934	4.229793	-0.903203	-0.556805	-1.894144

假设这组数据的最大值是3,那么可以将大于3的数设置为某个符合要求的数

pu[(np.abs(pu)>3)] = 3
pu.describe() #计算汇总统计,可以看到最大值是3
		0				1				2				3
count	1000.000000		1000.000000		1000.000000		1000.000000
mean	0.025300		0.006149		-0.047758		0.005119
std		1.007265		0.999293		0.993649		0.974995
min		-2.917087		-2.946565		-2.959961		-2.914630
25%		-0.652996		-0.720552		-0.741400		-0.677426
50%		-0.007727		0.044167		-0.036246		-0.030134
75%		0.672211		0.686266		0.635689		0.661967
max		3.000000		3.000000		3.000000		3.000000
2.7 排列和随机采样
dy = pd.DataFrame(np.arange(5*4).reshape(5,4))
dy
	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

随机排列(选取随机行数)

随机排列行索引,可以挑选任意行进行排列,但不能超过原有的行数

sam = np.random.permutation(3)  
sam
array([0, 2, 1])
dy.take(sam) 
	0	1	2	3
0	0	1	2	3
2	8	9	10	11
1	4	5	6	7

sample方法:随机选取行数,但不能超过原有的行数

dy.sample(n=3)
	0	1	2	3
4	16	17	18	19
1	4	5	6	7
0	0	1	2	3

replace参数:这个是作为参数而不是方法,为True时可重复选择,指定选取的行数可以大于原有的行数

dy.sample(n=8,replace=True)
	0	1	2	3
4	16	17	18	19
1	4	5	6	7
2	8	9	10	11
2	8	9	10	11
2	8	9	10	11
3	12	13	14	15
4	16	17	18	19
3	12	13	14	15
cn = pd.Series([1,2,3,4,5])
cn
0    1
1    2
2    3
3    4
4    5
dtype: int64

replace参数:为True时可重复选择,指定选取的行数可以大于原有的行数

cn.sample(n=10,replace=True)
4    5
3    4
4    5
0    1
3    4
1    2
0    1
2    3
4    5
4    5
dtype: int64
3.字符串操作
3.1 字符串方法
val = 'a,b, c'
val
'a,b, c'

split() 分割字符串

val.split(',') #按逗号进行分割
['a', 'b', ' c']

strip() 方法去除字符串空格

#去除字符串空格strip()方法
b = [x.strip() for x in val.split(',')]
b
['a', 'b', 'c']

join() 方法整合字符串

#整合字符串
a,s,f = b
a+'::'+s+'::'+f
'a::b::c'
#join()方法整合字符串
'::'.join(b)
'a::b::c'

检测字符串c是否在b中

#检测字符串c是否在b中
'c' in b
True

index 检测b是否在字符串val中,获取下标值

val.index('b')#检测b是否在字符串val中,获取下标值
2
val.index(',')#检测逗号是否在字符串val中,获取下标值
1
c = ['a',',','b']
c.index(',')      #检测列表b中是否有逗号字符串,获取下标值
1

find() 方法:找到返回下标值,找不到返回-1

#find()方法:找到返回下标值,找不到返回-1
val.find(',')
1
#find()方法:找到返回下标值,找不到返回-1
val.find('h')
-1

replace() 方法:第二个参数替换第一个参数

#replace方法:第二个参数替换第一个参数
val.replace(',' , '')  #表示用空格替换字符串val的逗号(,)
'ab c'
val.replace(',' , ':')#表示用冒号(:)替换字符串val的逗号(,)
'a:b: c'
3.2 正则表达式
import re
text = "foo  bar\t bat  \tqq"
re.split('\s+',text)  #'\s+'表示空格、制表符\t,换行符\n等
['foo', 'bar', 'bat', 'qq']

\s 表示空白字符,包括但不限于空格、回车(\r)、换行(\n)、tab或者叫水平制表符(\t)等

+ 是重复修饰符,表示它前面与它紧邻的表达式格式相匹配的字符串至少出现一个,上不封顶

\s+ 意思就是至少有一个空白字符存在

res = re.compile('\s+')  #编译正则表达式
res.split(text)
['foo', 'bar', 'bat', 'qq']

根据编译的正则表达式分割字符串text

reg = res.split(text)
reg
['foo', 'bar', 'bat', 'qq']

**findall()**方法查找

#findall()方法查找
res.findall(text)  #查找text中符合res正则表达式要求的字符('\s+'表示空格、制表符\t,换行符\n等)
['  ', '\t ', '  \t']
re.findall(res,text) #同上
['  ', '\t ', '  \t']

sub :替换字符串

#sub :替换字符串
re.sub(res,'6',text)  #将text字符串中符合res正则表达式的字符替换为字符6
'foo6bar6bat6qq'

match() 方法 :匹配字符串的第一个字符,如果匹配到则返回一个匹配项对象,否则返回None

#match()方法 :匹配字符串的第一个字符,如果匹配到则返回一个匹配项对象,否则返回None
# text = "foo  bar\t bat  \tqq"
t = re.match('f',text)   #从字符串text中匹配字符f(f是text的第一个字符),返回<re.Match object; span=(0, 1), match='f'>匹配项对象
t1 = re.match('b',text)  #b属于text字符串的字符,但不是第一个,返回None
t2 = re.match('y',text)   #y不属于text字符串,返回None
print(t)
print("="*20)
print(t1)
print("="*20)
print(t2)
<re.Match object; span=(0, 1), match='f'>
====================
None
====================
None

search() 方法:扫描整个字符串,可以匹配目标字符串的任意位置,找到则返回一个匹配项对象,否则返回None

#search()方法:扫描整个字符串,可以匹配目标字符串的任意位置,找到则返回一个匹配项对象,否则返回None
# text = "foo  bar\t bat  \tqq"
g1 = re.search('f',text)  
g2 = re.search('b',text)  #字符 f,b,q 都属于text字符串,返回一个匹配项对象
g3 = re.search('q',text) 
g4 = re.search('h',text)  #字符h不属于text字符串,返回None
print(g1)
print("="*20)
print(g2)
print("="*20)
print(g3)
print(t)
print("="*20)
print(g4)
<re.Match object; span=(0, 1), match='f'>
====================
<re.Match object; span=(5, 6), match='b'>
====================
<re.Match object; span=(16, 17), match='q'>
<re.Match object; span=(0, 1), match='f'>
====================
None
3.3 pandas的矢量化字符串函数
pty = {'a': 'dave@qq.com', 'b': 'steve@gmail.com',
        'c': 'sam@gmail.com', 'd': np.nan}
pty = pd.Series(pty)   # 根据字典生成一个Series对象
pty
a        dave@qq.com
b    steve@gmail.com
c      sam@gmail.com
d                NaN
dtype: object

NAN为浮点类型,不可使用split()分割,要用str.split()

pty.map(lambda x :x.split('@')) 
...
AttributeError: 'float' object has no attribute 'split'

contains:判断字符串是否包含(指定的字符或字符串等),返回一个布尔值

pty.str.contains('gmail')
a    False
b     True
c     True
d      NaN
dtype: object

字符串分割str.split()

pty.str.split('@')  #按 @ 进行分割
a        [dave, qq.com]
b    [steve, gmail.com]
c      [sam, gmail.com]
d                   NaN
dtype: object

分割字符串后根据下标取值

pty.str.split('@')[1]
['steve', 'gmail.com']
pty.str.split('@')[1][1]
'gmail.com'

查找findall()

# 查找
pty.str.findall('@')
a    [@]
b    [@]
c    [@]
d    NaN
dtype: object
#切片查找
pty.str[:5]   #获取前5个字符
a    dave@
b    steve
c    sam@g
d      NaN
dtype: object
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值