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