Python_tips-pandas模糊匹配

万壑松风知客来,摇扇抚琴待留声

1. 简介

好吧,不用等很久了,刚写完一篇又想到了一个比较实用的小技巧,当然由于内容篇幅较小,所以这里可以先简单介绍下,如果后面有相关内容再做补充即可。因为上一篇介绍了关于 Grouper 的使用,其中的例子用了时间序列的数据,所以这里可以对时间数据进行筛选数据集,比如筛选可以1:直接利用时间格式类型的数据进行选择;2:使用字符串格式时间进行选择。(主要是想熟悉下这个模糊匹配,每次使用都会忘)

2. 时间格式筛选

这是很简单,很容易想到的一种方式,数据本身是时间格式,就可以根据时间的起点、终点来取截取。操作如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
import pandas as pd
import numpy as np

# 生成1到4月的数据
b = pd.date_range(start='2019-01-01', end='2019-04-30', freq='D')
a = np.arange(0,b.shape[0])
c = np.random.randint(0, 10, size=b.shape[0])
df = pd.DataFrame({'a':a, 'date':b, 'c':c})

# a date c
# 0 0 2019-01-01 2
# 1 1 2019-01-02 1
# 2 2 2019-01-03 8
1
2
3
4
5
6
7
8
9
10
# 根据时间起点、终点来截取数据集三月份的数据
df_3 = df[df['date'] > '2019-02-28']
df_3 = df_3[df_3['date'] < '2019-04-01']

# a date c
# 59 59 2019-03-01 5
# 60 60 2019-03-02 5
# ......
# 88 88 2019-03-30 0
# 89 89 2019-03-31 5

3. 字符串模糊匹配

很多时候我们拿到的时间列并不是时间格式,更多可能是字符串格式的数据,如果每次都将这些字符串转换成时间格式,然后再截取,写冗余代码是很脑残的,所以对字符串的截取还是很有必要的,其中的一种方式,我们可以使用模糊匹配的方式,下面简单描述下。

1
2
3
4
5
# 当然首先将前面的时间格式转换成字符串格式,这可不是冗余操作,以便后续操作
# 这是两种时间格式转换成字符串的操作方式

# df['date'] = df['date'].map(lambda x : str(x))
df['date'] = df['date'].map(lambda x : x.strftime("%Y-%m-%d"))
1
2
3
4
5
6
7
8
9
# 使用正则匹配规则,模糊匹配三月份数据集,得到相同的结果
df = df[df['date'].str.contains(r'.*?-04-.')]

# a date c
# 59 59 2019-03-01 5
# 60 60 2019-03-02 5
# ......
# 88 88 2019-03-30 0
# 89 89 2019-03-31 5

.str.contains() 中的 str 可以理解成将 Series 数据结构转化为 String 格式,然后使用 contains() 方法匹配数据。

其实该方法还可以扩展,我们可以结合 &、|(与或),两种方法组合筛选数据。比如这里,我们可以同时模糊匹配出三月和四月的数据。

1
2
3
4
5
6
7
8
df = df[df['date'].str.contains(r'.*?-03-.|.*?-04-.')]

# a date c
# 59 59 2019-03-01 8
# 60 60 2019-03-02 4
# ......
# 118 118 2019-04-29 7
# 119 119 2019-04-30 0

这种方法有点像 SQL 中的 like ,当然其中的匹配规则自己定义难度不大。

4. 总结

简短的文章,总是让人还没有写过瘾就结束了。如果正常下一次的 Pyton_tips 应该会隔一段时间。期待下一次是哪个幸运的小方法将会走入这个系列。