pandas模块
pandas基于Numpy,可以看成是处理文本或者表格数据。pandas中有两个主要的数据结构,其中Series数据结构类似于Numpy中的一维数组,DataFrame类似于多维表格数据结构。
pandas是python数据分析的核心模块。它主要提供了五大功能:
1.支持文件存取操作,支持数据库(sql)、html、json、pickle、csv(txt、excel)、sas、stata、hdf等。
2.支持增删改查、切片、高阶函数、分组聚合等单表操作,以及和dict、list的互相转换。
3.支持多表拼接合并操作。
4.支持简单的绘图操作。
5.支持简单的统计分析操作。
Series
import numpy as np
import pandas as pd
arr = np.array([1, 2, 3, 4, np.nan, ])
print(arr)
[ 1. 2. 3. 4. nan]
s = pd.Series(arr)
print(s)
0 1.0
1 2.0
2 3.0
3 4.0
4 NaN
dtype: float64
DataFrame
dates = pd.date_range('20190101', periods=6)
print(dates)
DatetimeIndex(['2019-01-01', '2019-01-02', '2019-01-03', '2019-01-04',
'2019-01-05', '2019-01-06'],
dtype='datetime64[ns]', freq='D')
import random
np.random.seed(1)
arr = 10*np.random.randn(6, 4)
print(arr)
[[ 16.24345364 -6.11756414 -5.28171752 -10.72968622]
[ 8.65407629 -23.01538697 17.44811764 -7.61206901]
[ 3.19039096 -2.49370375 14.62107937 -20.60140709]
[ -3.22417204 -3.84054355 11.33769442 -10.99891267]
[ -1.72428208 -8.77858418 0.42213747 5.82815214]
[-11.00619177 11.4472371 9.01590721 5.02494339]]
df = pd.DataFrame(arr, index=dates, columns=['c1', 'c2', 'c3', 'c4'])
df
|
c1 |
c2 |
c3 |
c4 |
2019-01-01 |
16.243454 |
-6.117564 |
-5.281718 |
-10.729686 |
2019-01-02 |
8.654076 |
-23.015387 |
17.448118 |
-7.612069 |
2019-01-03 |
3.190391 |
-2.493704 |
14.621079 |
-20.601407 |
2019-01-04 |
-3.224172 |
-3.840544 |
11.337694 |
-10.998913 |
2019-01-05 |
-1.724282 |
-8.778584 |
0.422137 |
5.828152 |
2019-01-06 |
-11.006192 |
11.447237 |
9.015907 |
5.024943 |
# 使用pandas读取字典形式的数据
df2 = pd.DataFrame({'a': 1, 'b': [2, 3], 'c': np.arange(2), 'd': 'hello'})
df2
|
a |
b |
c |
d |
0 |
1 |
2 |
0 |
hello |
1 |
1 |
3 |
1 |
hello |
DataFrame属性
属性 |
详解 |
dtype |
查看数据类型 |
index |
查看行序列或者索引 |
columns |
查看各列的标签 |
values |
查看数据框内的数据,也即不含表头索引的数据 |
describe |
查看数据每一列的极值、均值、中位数、只可用于数值型数据 |
transpose |
转置,也可用T来操作 |
sort_index |
排序,可按行或列index排序输出 |
sort_values |
按数据值来排序 |
# 查看数据类型
print(df2.dtypes)
a int64
b int64
c int32
d object
dtype: object
df
|
c1 |
c2 |
c3 |
c4 |
2019-01-01 |
16.243454 |
-6.117564 |
-5.281718 |
-10.729686 |
2019-01-02 |
8.654076 |
-23.015387 |
17.448118 |
-7.612069 |
2019-01-03 |
3.190391 |
-2.493704 |
14.621079 |
-20.601407 |
2019-01-04 |
-3.224172 |
-3.840544 |
11.337694 |
-10.998913 |
2019-01-05 |
-1.724282 |
-8.778584 |
0.422137 |
5.828152 |
2019-01-06 |
-11.006192 |
11.447237 |
9.015907 |
5.024943 |
print(df.index)
DatetimeIndex(['2019-01-01', '2019-01-02', '2019-01-03', '2019-01-04',
'2019-01-05', '2019-01-06'],
dtype='datetime64[ns]', freq='D')
print(df.columns)
Index(['c1', 'c2', 'c3', 'c4'], dtype='object')
print(df.values)
[[ 16.24345364 -6.11756414 -5.28171752 -10.72968622]
[ 8.65407629 -23.01538697 17.44811764 -7.61206901]
[ 3.19039096 -2.49370375 14.62107937 -20.60140709]
[ -3.22417204 -3.84054355 11.33769442 -10.99891267]
[ -1.72428208 -8.77858418 0.42213747 5.82815214]
[-11.00619177 11.4472371 9.01590721 5.02494339]]
df.describe()
|
c1 |
c2 |
c3 |
c4 |
count |
6.000000 |
6.000000 |
6.000000 |
6.000000 |
mean |
2.022213 |
-5.466424 |
7.927203 |
-6.514830 |
std |
9.580084 |
11.107772 |
8.707171 |
10.227641 |
min |
-11.006192 |
-23.015387 |
-5.281718 |
-20.601407 |
25% |
-2.849200 |
-8.113329 |
2.570580 |
-10.931606 |
50% |
0.733054 |
-4.979054 |
10.176801 |
-9.170878 |
75% |
7.288155 |
-2.830414 |
13.800233 |
1.865690 |
max |
16.243454 |
11.447237 |
17.448118 |
5.828152 |
df.T
|
2019-01-01 00:00:00 |
2019-01-02 00:00:00 |
2019-01-03 00:00:00 |
2019-01-04 00:00:00 |
2019-01-05 00:00:00 |
2019-01-06 00:00:00 |
c1 |
16.243454 |
8.654076 |
3.190391 |
-3.224172 |
-1.724282 |
-11.006192 |
c2 |
-6.117564 |
-23.015387 |
-2.493704 |
-3.840544 |
-8.778584 |
11.447237 |
c3 |
-5.281718 |
17.448118 |
14.621079 |
11.337694 |
0.422137 |
9.015907 |
c4 |
-10.729686 |
-7.612069 |
-20.601407 |
-10.998913 |
5.828152 |
5.024943 |
# 按索引从小到大排序
df.sort_index(axis=0)
|
c1 |
c2 |
c3 |
c4 |
2019-01-01 |
16.243454 |
-6.117564 |
-5.281718 |
-10.729686 |
2019-01-02 |
8.654076 |
-23.015387 |
17.448118 |
-7.612069 |
2019-01-03 |
3.190391 |
-2.493704 |
14.621079 |
-20.601407 |
2019-01-04 |
-3.224172 |
-3.840544 |
11.337694 |
-10.998913 |
2019-01-05 |
-1.724282 |
-8.778584 |
0.422137 |
5.828152 |
2019-01-06 |
-11.006192 |
11.447237 |
9.015907 |
5.024943 |
# 按索引从大到小排序
df2.sort_index(axis=1)
|
a |
b |
c |
d |
0 |
1 |
2 |
0 |
hello |
1 |
1 |
3 |
1 |
hello |
# 按b列的值从大到小排序
df2.sort_values(by='b', ascending=False) # ascending 默认为True
|
a |
b |
c |
d |
1 |
1 |
3 |
1 |
hello |
0 |
1 |
2 |
0 |
hello |
处理缺失值
from io import StringIO
test_data = '''
5.1,,1.4,0.2
4.9,3.0,1.4,0.2
4.7,3.2,,0.2
7.0,3.2,4.7,1.4
6.4,3.2,4.5,1.5
6.9,3.1,4.9,
,,,
'''
test_data = StringIO(test_data) # 把字符串读入内存
df = pd.read_csv(test_data)
df # 第一行数据成为了columns
|
5.1 |
Unnamed: 1 |
1.4 |
0.2 |
0 |
4.9 |
3.0 |
1.4 |
0.2 |
1 |
4.7 |
3.2 |
NaN |
0.2 |
2 |
7.0 |
3.2 |
4.7 |
1.4 |
3 |
6.4 |
3.2 |
4.5 |
1.5 |
4 |
6.9 |
3.1 |
4.9 |
NaN |
5 |
NaN |
NaN |
NaN |
NaN |
from io import StringIO
test_data = '''
c1,c2,'c3','c4'
5.1,,1.4,0.2
4.9,3.0,1.4,0.2
4.7,3.2,,0.2
7.0,3.2,4.7,1.4
6.4,3.2,4.5,1.5
6.9,3.1,4.9,
,,,
'''
test_data = StringIO(test_data) # 把这个读入内存
df = pd.read_csv(test_data)
df
|
c1 |
c2 |
'c3' |
'c4' |
0 |
5.1 |
NaN |
1.4 |
0.2 |
1 |
4.9 |
3.0 |
1.4 |
0.2 |
2 |
4.7 |
3.2 |
NaN |
0.2 |
3 |
7.0 |
3.2 |
4.7 |
1.4 |
4 |
6.4 |
3.2 |
4.5 |
1.5 |
5 |
6.9 |
3.1 |
4.9 |
NaN |
6 |
NaN |
NaN |
NaN |
NaN |
# 0是行,1是列 (与numpy相反)
df.dropna(axis=0) # 把含有NaN的行去掉
|
c1 |
c2 |
'c3' |
'c4' |
1 |
4.9 |
3.0 |
1.4 |
0.2 |
3 |
7.0 |
3.2 |
4.7 |
1.4 |
4 |
6.4 |
3.2 |
4.5 |
1.5 |
df.dropna(axis=1) # 把含有NaN的列去掉
df
|
c1 |
c2 |
'c3' |
'c4' |
0 |
5.1 |
NaN |
1.4 |
0.2 |
1 |
4.9 |
3.0 |
1.4 |
0.2 |
2 |
4.7 |
3.2 |
NaN |
0.2 |
3 |
7.0 |
3.2 |
4.7 |
1.4 |
4 |
6.4 |
3.2 |
4.5 |
1.5 |
5 |
6.9 |
3.1 |
4.9 |
NaN |
6 |
NaN |
NaN |
NaN |
NaN |
df.dropna(thresh=3, axis=0) # 行里最少要有3个数字才留下来
|
c1 |
c2 |
'c3' |
'c4' |
0 |
5.1 |
NaN |
1.4 |
0.2 |
1 |
4.9 |
3.0 |
1.4 |
0.2 |
2 |
4.7 |
3.2 |
NaN |
0.2 |
3 |
7.0 |
3.2 |
4.7 |
1.4 |
4 |
6.4 |
3.2 |
4.5 |
1.5 |
5 |
6.9 |
3.1 |
4.9 |
NaN |
df.dropna(thresh=4, axis=0) # 行里最少要有4个数字才留下来
|
c1 |
c2 |
'c3' |
'c4' |
1 |
4.9 |
3.0 |
1.4 |
0.2 |
3 |
7.0 |
3.2 |
4.7 |
1.4 |
4 |
6.4 |
3.2 |
4.5 |
1.5 |
df.dropna(thresh=6, axis=1) # 列里最少要有6个数字才留下来
|
c1 |
0 |
5.1 |
1 |
4.9 |
2 |
4.7 |
3 |
7.0 |
4 |
6.4 |
5 |
6.9 |
6 |
NaN |
df
|
c1 |
c2 |
'c3' |
'c4' |
0 |
5.1 |
NaN |
1.4 |
0.2 |
1 |
4.9 |
3.0 |
1.4 |
0.2 |
2 |
4.7 |
3.2 |
NaN |
0.2 |
3 |
7.0 |
3.2 |
4.7 |
1.4 |
4 |
6.4 |
3.2 |
4.5 |
1.5 |
5 |
6.9 |
3.1 |
4.9 |
NaN |
6 |
NaN |
NaN |
NaN |
NaN |
df.columns
Index(['c1', 'c2', ''c3'', ''c4''], dtype='object')
df.dropna(subset=['c2']) # 把c2列里的含有NaN的行去掉
|
c1 |
c2 |
'c3' |
'c4' |
1 |
4.9 |
3.0 |
1.4 |
0.2 |
2 |
4.7 |
3.2 |
NaN |
0.2 |
3 |
7.0 |
3.2 |
4.7 |
1.4 |
4 |
6.4 |
3.2 |
4.5 |
1.5 |
5 |
6.9 |
3.1 |
4.9 |
NaN |
df.dropna(subset=["'c3'"]) # 把c3列里的含有NaN的行去掉
|
c1 |
c2 |
'c3' |
'c4' |
0 |
5.1 |
NaN |
1.4 |
0.2 |
1 |
4.9 |
3.0 |
1.4 |
0.2 |
3 |
7.0 |
3.2 |
4.7 |
1.4 |
4 |
6.4 |
3.2 |
4.5 |
1.5 |
5 |
6.9 |
3.1 |
4.9 |
NaN |
df.fillna(value=0) # 用0填充
|
c1 |
c2 |
'c3' |
'c4' |
0 |
5.1 |
0.0 |
1.4 |
0.2 |
1 |
4.9 |
3.0 |
1.4 |
0.2 |
2 |
4.7 |
3.2 |
0.0 |
0.2 |
3 |
7.0 |
3.2 |
4.7 |
1.4 |
4 |
6.4 |
3.2 |
4.5 |
1.5 |
5 |
6.9 |
3.1 |
4.9 |
0.0 |
6 |
0.0 |
0.0 |
0.0 |
0.0 |
合并数据
df1 = pd.DataFrame(np.zeros((3, 4)))
df1
|
0 |
1 |
2 |
3 |
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 |
df2 = pd.DataFrame(np.ones((3, 4)))
df2
|
0 |
1 |
2 |
3 |
0 |
1.0 |
1.0 |
1.0 |
1.0 |
1 |
1.0 |
1.0 |
1.0 |
1.0 |
2 |
1.0 |
1.0 |
1.0 |
1.0 |
pd.concat((df1, df2), axis=0)
|
0 |
1 |
2 |
3 |
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 |
0 |
1.0 |
1.0 |
1.0 |
1.0 |
1 |
1.0 |
1.0 |
1.0 |
1.0 |
2 |
1.0 |
1.0 |
1.0 |
1.0 |
pd.concat((df1, df2), axis=1)
|
0 |
1 |
2 |
3 |
0 |
1 |
2 |
3 |
0 |
0.0 |
0.0 |
0.0 |
0.0 |
1.0 |
1.0 |
1.0 |
1.0 |
1 |
0.0 |
0.0 |
0.0 |
0.0 |
1.0 |
1.0 |
1.0 |
1.0 |
2 |
0.0 |
0.0 |
0.0 |
0.0 |
1.0 |
1.0 |
1.0 |
1.0 |
取值
df
|
c1 |
c2 |
'c3' |
'c4' |
0 |
5.1 |
NaN |
1.4 |
0.2 |
1 |
4.9 |
3.0 |
1.4 |
0.2 |
2 |
4.7 |
3.2 |
NaN |
0.2 |
3 |
7.0 |
3.2 |
4.7 |
1.4 |
4 |
6.4 |
3.2 |
4.5 |
1.5 |
5 |
6.9 |
3.1 |
4.9 |
NaN |
6 |
NaN |
NaN |
NaN |
NaN |
dates = pd.date_range('20190101', periods=6)
np.random.seed(1)
arr = 10*np.random.randn(6, 4)
df = pd.DataFrame(arr, index=dates, columns=['c1', 'c2', 'c3', 'c4'])
df
|
c1 |
c2 |
c3 |
c4 |
2019-01-01 |
16.243454 |
-6.117564 |
-5.281718 |
-10.729686 |
2019-01-02 |
8.654076 |
-23.015387 |
17.448118 |
-7.612069 |
2019-01-03 |
3.190391 |
-2.493704 |
14.621079 |
-20.601407 |
2019-01-04 |
-3.224172 |
-3.840544 |
11.337694 |
-10.998913 |
2019-01-05 |
-1.724282 |
-8.778584 |
0.422137 |
5.828152 |
2019-01-06 |
-11.006192 |
11.447237 |
9.015907 |
5.024943 |
# 按照索引取值
df.loc['2019-01-01']
c1 16.243454
c2 -6.117564
c3 -5.281718
c4 -10.729686
Name: 2019-01-01 00:00:00, dtype: float64
# 类似于numpy取值
df.iloc[0, 0]
16.243453636632417
df.iloc[0, :] = 0
df
|
c1 |
c2 |
c3 |
c4 |
2019-01-01 |
0.000000 |
0.000000 |
0.000000 |
0.000000 |
2019-01-02 |
8.654076 |
-23.015387 |
17.448118 |
-7.612069 |
2019-01-03 |
3.190391 |
-2.493704 |
14.621079 |
-20.601407 |
2019-01-04 |
-3.224172 |
-3.840544 |
11.337694 |
-10.998913 |
2019-01-05 |
-1.724282 |
-8.778584 |
0.422137 |
5.828152 |
2019-01-06 |
-11.006192 |
11.447237 |
9.015907 |
5.024943 |
matplotlib模块
matplotlib是一个绘图库,它可以创建常用的统计图,包括条形图、箱型图、折线图、散点图和直方图。
条形图
import matplotlib.pyplot as plt
# 只识别英语,所以通过以下两行增加中文字体
from matplotlib.font_manager import FontProperties
# jupyter默认不显示图片,通过这一行告诉他显示图片
%matplotlib inline
font = FontProperties(fname=r'E:\msyh.ttc') # 中文字体
# 修改背景为条纹
plt.style.use('ggplot')
classes = ['3班', '4班', '5班', '6班']
classes_index = range(len(classes))
print(list(classes_index))
[0, 1, 2, 3]
student_amounts = [42, 53, 60, 66]
plt.bar(classes_index, student_amounts)
plt.xticks(classes_index, classes, FontProperties=font)
for ind, student_amount in enumerate(student_amounts):
plt.text(ind, student_amount+1, student_amount)
plt.xlabel('班级', fontproperties=font, fontsize=15)
plt.ylabel('学生人数', fontproperties=font, fontsize=15)
plt.title('班级-学生人数', fontproperties=font, fontsize=20)
# 保存图片,bbox_inches='tight'去掉图形四周的空白
# plt.savefig('classes_students.png', dpi=400, bbox_inches='tight')
plt.show()
直方图
import random
import numpy as np
import matplotlib.pyplot as plt
# 只识别英语,所以通过以下两行增加中文字体
from matplotlib.font_manager import FontProperties
# jupyter默认不显示图片,通过这一行告诉他显示图片
%matplotlib inline
font = FontProperties(fname=r'E:\msyh.ttc') # 中文字体
mu1, mu2, sigma = 50, 100, 10
x1 = mu1+sigma*np.random.randn(10000)
print(x1)
[59.00855949 43.16272141 48.77109774 ... 57.94645859 54.70312714
58.94125528]
x2 = mu2+sigma*np.random.randn(10000)
print(x2)
[115.19915511 82.09208214 110.88092454 ... 95.0872103 104.21549068
133.36025251]
plt.style.use('ggplot')
fig = plt.figure()
# 1行2列
# 1,1,1表示一张画布切割成1行1列共一张图的第1个;2,2,1表示一张画布切割成2行2列共4张图的第一个(左上角)
ax1 = fig.add_subplot(121)
ax1.hist(x1, bins=100, color='red')
ax1.set_title('红色', fontproperties=font)
ax2 = fig.add_subplot(122)
ax2.hist(x2, bins=100, color='blue')
ax2.set_title('蓝色', fontproperties=font)
fig.suptitle('大标题', fontproperties=font, fontsize=15, weight='bold')
plt.show()
折线图
import random
import numpy as np
import matplotlib.pyplot as plt
# 只识别英语,所以通过以下两行增加中文字体
from matplotlib.font_manager import FontProperties
# jupyter默认不显示图片,通过这一行告诉他显示图片
%matplotlib inline
font = FontProperties(fname=r'E:\msyh.ttc') # 中文字体
plt.style.use('ggplot')
np.random.seed(1)
data1 = np.random.rand(40).cumsum()
data2 = np.random.rand(40).cumsum()
data3 = np.random.rand(40).cumsum()
data4 = np.random.rand(40).cumsum()
plt.plot(data1, color='r', linestyle='-', alpha=0.5, label='红色')
plt.plot(data2, color='green', linestyle='--', label='绿色')
plt.plot(data3, color='pink', linestyle=':', label='粉色')
plt.plot(data4, color='orange', linestyle='-.', label='橙色')
plt.legend(prop=font)
plt.show()
散点图
import random
import numpy as np
import matplotlib.pyplot as plt
# 只识别英语,所以通过以下两行增加中文字体
from matplotlib.font_manager import FontProperties
# jupyter默认不显示图片,通过这一行告诉他显示图片
%matplotlib inline
font = FontProperties(fname=r'E:\msyh.ttc') # 中文字体
x = np.arange(1, 20)
x
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19])
y_linear = x**2
y_linear
array([ 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169,
196, 225, 256, 289, 324, 361], dtype=int32)
y_log = np.log(x)
y_log
array([0. , 0.69314718, 1.09861229, 1.38629436, 1.60943791,
1.79175947, 1.94591015, 2.07944154, 2.19722458, 2.30258509,
2.39789527, 2.48490665, 2.56494936, 2.63905733, 2.7080502 ,
2.77258872, 2.83321334, 2.89037176, 2.94443898])
fig = plt.figure()
ax1 = fig.add_subplot(121)
ax1.scatter(x, y_linear, color='red', marker='o', s=50)
ax1.scatter(x, y_log, color='blue', marker='*', s=30)
ax1.set_title('scatter')
ax2 = fig.add_subplot(122)
ax2.plot(x, y_linear)
ax2.plot(x, y_log)
ax2.set_title('plot')
plt.plot
plt.show()
re模块
正则表达式本身是一种小型的、高度专业化的编程语言,它并不是Python的一部分。正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大。得益于这一点,在提供了正则表达式的语言里,正则表达式的语法都是一样的,区别只在于不同的编程语言实现支持的语法数量不同;但不用担心,不被支持的语法通常是不常用的部分。如果已经在其他语言里使用过正则表达式,只需要简单看一看就可以上手了。而在python中,通过内嵌集成re模块,程序员们可以直接调用来实现正则匹配。正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎执行。
import re
s = '孙悟空找猪八戒找媳妇高翠兰,然后吃西瓜'
print(s[10:13])
print(s[s.index('媳妇') + 2:s.index('媳妇') + 5])
# re模块,从字符串(文本)里面找特定的东西
res = re.findall('媳妇(.{3})', s)
print(res)
print(res[0])
高翠兰
高翠兰
['高翠兰']
高翠兰
基础的re使用
import re
s = '孙悟空#$__%#124aba4找猪八戒 找找找找媳妇西高翠兰,找西瓜,再吃西瓜'
res = re.findall('西瓜', s)
print(res)
['西瓜', '西瓜']
^
叫作元字符,元字符会有特殊意义,^
匹配开头,也就是说从头找
res = re.findall('^孙悟空', s)
print(res)
['孙悟空']
res = re.findall('^猪八戒', s)
print(res)
[]
$
从尾部匹配,放在字符串最后
res = re.findall('吃西瓜$', s)
print(res)
['吃西瓜']
res = re.findall('吃西$', s)
print(res)
[]
|
相当于 or
res = re.findall('孙悟空|西瓜', s)
print(res)
['孙悟空', '西瓜', '西瓜']
[]
找到 [ ] 内所有元素
res = re.findall("['孙悟空','西瓜','吃']", s)
print(res)
print('*'*20)
res = re.findall("[孙悟空'西瓜'吃]", s)
print(res)
['孙', '悟', '空', '西', ',', '西', '瓜', ',', '吃', '西', '瓜']
********************
['孙', '悟', '空', '西', '西', '瓜', '吃', '西', '瓜']
.
代表任意一个字符
res = re.findall('媳妇..', s)
print(res)
print('*'*20)
res = re.findall('媳妇....', s)
print(res)
['媳妇西高']
********************
['媳妇西高翠兰']
- {n},大括号前的字符匹配n次,没有这么多就找不到
res = re.findall('找{3}', s)
print(res)
print('*'*20)
res = re.findall('找{8}', s)
print(res)
['找找找']
********************
[]
*
前面字符匹配0-∞个
res = re.findall('找*媳妇', s)
print(res)
print('*'*20)
res = re.findall('西瓜瓜*', s)
print(res)
['找找找找媳妇']
********************
['西瓜', '西瓜']
+
前面的字符匹配1-∞个
res = re.findall('找+媳妇', s)
print(res)
print('*'*20)
res = re.findall('西瓜瓜+', s)
print(res)
['找找找找媳妇']
********************
[]
\d
匹配数字
res = re.findall('\d', s)
print(res)
['1', '2', '4', '4']
res = re.findall('\d+', s)
print(res)
['124', '4']
\D
,除了数字都匹配
res = re.findall('\D', s)
print(res)
print('*'*20)
res = re.findall('\D+', s)
print(res)
['孙', '悟', '空', '#', '$', '_', '_', '%', '#', 'a', 'b', 'a', '找', '猪', '八', '戒', ' ', ' ', ' ', ' ', '找', '找', '找', '找', '媳', '妇', '西', '高', '翠', '兰', ',', '找', '西', '瓜', ',', '再', '吃', '西', '瓜']
********************
['孙悟空#$__%#', 'aba', '找猪八戒 找找找找媳妇西高翠兰,找西瓜,再吃西瓜']
\s
,匹配空
res = re.findall('\s+', s)
print(res)
[' ']
\S
,匹配非空
res = re.findall('\S+', s)
print(res)
['孙悟空#$__%#124aba4找猪八戒', '找找找找媳妇西高翠兰,找西瓜,再吃西瓜']
\w
,匹配字母、数字、下划线
res = re.findall('\w+', s)
print(res)
['孙悟空', '__', '124aba4找猪八戒', '找找找找媳妇西高翠兰', '找西瓜', '再吃西瓜']
\W
,非字母、非数字、非下划线
res = re.findall('\W+', s)
print(res)
['#$', '%#', ' ', ',', ',']
贪婪模式
res = re.findall('猪.*兰', s)
print(res)
res = re.findall('猪.*瓜', s)
print(res)
['猪八戒 找找找找媳妇西高翠兰']
['猪八戒 找找找找媳妇西高翠兰,找西瓜,再吃西瓜']
非贪婪模式
?
就是停止符,找到一个就停止
res = re.findall('猪.*?瓜', s)
print(res)
['猪八戒 找找找找媳妇西高翠兰,找西瓜']
re模块高级
compile
写一个通用的规则模板
import re
s = '孙悟空#$__%#124aba4找猪八戒 找找找找媳妇西高翠兰,找西瓜,再吃西瓜'
res1 = re.compile('\d+')
res2 = re.compile('\w+')
res3 = re.compile('\s+')
result1 = res1.findall(s)
result2 = res2.findall(s)
result3 = res3.findall(s)
print(result1)
print(result2)
print(result3)
phone_compile = re.compile('1\d{10}')
email_compile = re.compile('\w+@\w+.\w+')
test_s = '12345678900 nickchen121@163.com 2287273393@qq.com'
res = phone_compile.findall(test_s)
print(res)
res = email_compile.findall(test_s)
print(res)
['124', '4']
['孙悟空', '__', '124aba4找猪八戒', '找找找找媳妇西高翠兰', '找西瓜', '再吃西瓜']
[' ']
['12345678900']
['nickchen121@163.com', '2287273393@qq.com']
match和search
match和search的区别,match从开头开始匹配找一个,search搜索所有找第一个
import re
s = '猪八戒找媳妇猪八戒'
match_res = re.match('猪八戒', s)
print(match_res.group())
search_res = re.search('猪八戒', s)
print(search_res.group())
猪八戒
猪八戒
分组
需要的东西括号就行了,括号外的就不打印了
import re
s = '猪八戒的媳妇是高翠兰,孙悟空的媳妇是白骨精,唐僧的媳妇是女儿国王,沙悟净没有媳妇(py9的学生们)'
res = re.findall('(.*?)的媳妇是(.*?),', s)
print(res)
[('猪八戒', '高翠兰'), ('孙悟空', '白骨精'), ('唐僧', '女儿国王')]
re.split()
字符串的split方法相似,区别是可以用正则表达式去替换
import re
s = '猪八戒的媳妇是1高翠兰,孙悟空的媳妇是2白骨精,唐僧的媳妇是3女儿国王,沙悟净没有媳妇(py9的学生们)'
print(s.split(','))
res = re.split('\d+', s)
print(res)
['猪八戒的媳妇是1高翠兰', '孙悟空的媳妇是2白骨精', '唐僧的媳妇是3女儿国王', '沙悟净没有媳妇(py9的学生们)']
['猪八戒的媳妇是', '高翠兰,孙悟空的媳妇是', '白骨精,唐僧的媳妇是', '女儿国王,沙悟净没有媳妇(py', '的学生们)']
s = '猪八戒的媳妇是a高翠兰,孙悟空的媳A妇是b白骨精,唐僧的B媳妇是z女儿国王,沙悟净没有媳妇(py9的学生们)'
print(s.split(','))
res = re.split('[a-zA-Z]', s) # a,b,c,
print(res)
['猪八戒的媳妇是a高翠兰', '孙悟空的媳A妇是b白骨精', '唐僧的B媳妇是z女儿国王', '沙悟净没有媳妇(py9的学生们)']
['猪八戒的媳妇是', '高翠兰,孙悟空的媳', '妇是', '白骨精,唐僧的', '媳妇是', '女儿国王,沙悟净没有媳妇(', '', '9的学生们)']
sub和subn
他们都是替换内容,但是subn会计算替换了多少次,和字符串的replace内置方法类似。
import re
s = '猪八戒的媳妇是1高翠兰,孙悟空的媳妇是2白骨精,唐僧的媳妇是3女儿国王,沙悟净6没有媳妇(py9的学生们)'
print(re.sub('\d', '', s))
print(re.subn('\d', '', s)) # 除了会修改内容,还会返回修改了多少次
猪八戒的媳妇是高翠兰,孙悟空的媳妇是白骨精,唐僧的媳妇是女儿国王,沙悟净没有媳妇(py的学生们)
('猪八戒的媳妇是高翠兰,孙悟空的媳妇是白骨精,唐僧的媳妇是女儿国王,沙悟净没有媳妇(py的学生们)', 5)