3a2d4b081d13a1b9d666cb7b43aa2aaf.jpeg 


 CDA数据分析师 出品  

作者:  张彦存

编译: Mika

Pandas中字符串的操作是相当的灵活,内置了大量的相关方法用于字符串的加工处理,并且许多方法都是支持正则表达式的。

筛选包含特定字符串的列可以根据特定字符串在列名中的位置有这么几种情形:

  • 这个特定字符串在列名首

  • 这个特定字符串在列名尾

  • 这个特定字符串在列名中

  • 这个特定字符串在列名的任意位置上

筛选特定的列数据基本有两种思路:

  • 使用pandas字符串方法+布尔索引

  • 使用pandas提供的filter进行筛选

使用pandas字符串方法+布尔索引

为处理字符串数据,Pandas通过.str提供了许多字符串处理方法:

  • contains 判断某字符串中是否包含

  • startswith

  • endswith

这些方法均返回布尔值的序列,可用于布尔索引。

import pandas as pd
data = pd.DataFrame({'A1':[1,2,3],'B1':[1,2,3],"1B11":[4,5,6],"11B":[4,3,7]})
data

A1B11B1111B
01144
12253
23367

这个特定字符串在列名的任意位置上

例如筛选列名中包含B的列,这时只需给contains传入字符串'B'即可得到布尔数组

data.columns.str.contains('B')
array([False,  True,  True,  True])

使用上述布尔数组作为索引,筛选符合要求的列

data.loc[:,data.columns.str.contains('B')]

B11B1111B
0144
1253
2367

如果特定字符并不是某一具体的字符串,而是某一类的字符串,比如包含两个连续数字或其他特征,这时候也可以结合正则表达式来实现筛选。

data.columns.str.contains('\d{2}',regex=True)
array([False, False,  True,  True])

regex=True 表示正在使用正则表达式 \d{2} 表示两个数字构成的字符串,使用上述代码得到相应的布尔数组,进行布尔索引即可。

data.loc[:,data.columns.str.contains('\d{2}',regex=True)]

1B1111B
044
153
267

1B11 11B中均包含两个连续的数字,因此符合条件

这个特定字符在字符串的开头

比如要求这特定的字符必须在字符串的开头,可以使用startswith

data.columns.str.startswith("B")
array([False,  True, False, False])

上述代码筛选以B开头的列

data.loc[:,data.columns.str.startswith("B")]

B1
01
12
23

这样就筛选出了符合条件的列。如果不是固定的字符,而是某一类字符,那么这时候需要使用contains+正则表达式的组合,startswith不支持正则表达式。

data.columns.str.contains("^\d{2}",regex=True)
array([False, False, False,  True])

正则表达式"^\d{2}"表示以两个数字开头的字符串

data.loc[:,data.columns.str.contains("^\d{2}",regex=True)]

11B
04
13
27

这个特定字符在字符串的尾部

比如要求这特定的字符必须在字符串的尾部,可以使用endswith

data.columns.str.endswith("B")
array([False, False, False,  True])

上述代码筛选以B结尾的列,得到相应的布尔数组,使用布尔数组筛选数据,代码如下:

data.loc[:,data.columns.str.endswith("B")]

11B
04
13
27

这样就筛选出了符合条件的列。如果不是固定的字符,而是某一类字符,那么这时候需要使用contains+正则表达式的组合,endswith不支持正则表达式。

data.columns.str.contains("\d{2}$",regex=True)
array([False, False,  True, False])

正则表达式"\d{2}$"表示以两个数字结尾的字符串

data.loc[:,data.columns.str.contains("\d{2}$",regex=True)]

1B11
04
15
26

这个特定字符串在字符串的中部

这种需求需要使用正则表达式来去实现

data.columns.str.contains("^[^B]+B[^B]+$",regex=True)
array([False, False,  True, False])

正则表达式"^[^B]+B[^B]+$"表示以非B字符开头、结尾且包含B的列名

data.loc[:,data.columns.str.contains("^[^B]+B[^B]+$",regex=True)]

1B11
04
15
26

当然在进行字符串处理的过程中除了使用字符串特定函数之外还可以使用map apply 再结合自定义函数实现更复杂的处理

使用pandas提供的filter进行筛选

Pandas 的 filter 方法根据指定的索引标签对数据框行或列查询子集。
DataFrame 使用时的语法为:

df.filter(
    items=None,
    like: 'str | None' = None,
    regex: 'str | None' = None,
    axis=None,
) -> 'FrameOrSeries'

参数:

  • items:list-like,对应轴的标签名列表

  • like:str,支持对应标签名的模糊名查询

  • regex:str (正则表达式),按正则表达式查询标签名

  • axis:{0 or ‘index’, 1 or ‘columns’, None}, default None,要筛选的轴,表示为索引(int)或轴名称(str)。默认情况下为列名,‘index’ 为 Series, ‘columns’ 为 DataFrame

返回:

与输入对象类型相同

需要注意的是,此方法不会对数据帧的数据内容进行过滤,仅应用于按标签筛选。

其中的参数 items, like, 和 regex parameters 被强制执行为相互排斥,即只能有一个存在。

筛选列名中间包括B的可以直接使用正则表达式筛选,代码如下:

data.filter(regex="^[^B]+B[^B]+$",axis=1)

1B11
04
15
26

筛选列名以两个数字结尾的列,代码如下:

data.filter(regex="\d{2}$",axis=1)

1B11
04
15
26

2819838011af2ab11ad3393fbd53400f.png

1b331de5fb18f20a96639938f1b6607e.png

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐