Fork me on GitHub

Pandas处理文本的3大秘诀

Pandas文本处理大全的3大秘诀

本文介绍Pandas中针对文本数据处理的方法。文本数据也就是我们常说的字符串,Pandas 为 Series 提供了 str 属性,通过它可以方便的对每个元素进行操作。

首先需要清楚的是:Python中原生的字符串操作的相关的函数也是适用的。

1
2
import pandas as pd
import numpy as np

模拟数据

1
2
3
4
5
6
7
8
df = pd.DataFrame({
"name":["xiao ming","xiao zhang",np.nan,"sun quan","guan yu"],
"age":[22,19,20,34,39],
"sex":["male","Female","female","Female","male"],
"address":[" 广东省 深圳市 ","浙江省 杭州市"," 江苏省苏州市 ","福建省 泉州市","广东省广州市"]
})

df
name age sex address
0 xiao ming 22 male 广东省 深圳市
1 xiao zhang 19 Female 浙江省 杭州市
2 NaN 20 female 江苏省苏州市
3 sun quan 34 Female 福建省 泉州市
4 guan yu 39 male 广东省广州市
1
df.dtypes
name       object
age         int64
sex        object
address    object
dtype: object

字母转换函数

在Python原生的字符串转换中有upper、lower、title等函数和字母转换相关

upper

将字母全部转成大写的形式

1
df["sex"].str.upper()
0      MALE
1    FEMALE
2    FEMALE
3    FEMALE
4      MALE
Name: sex, dtype: object

lower

将字母全部转成小写形式

1
df["sex"].str.lower()
0      male
1    female
2    female
3    female
4      male
Name: sex, dtype: object

capitalize

第一个单词的首字母大写

1
df["name"].str.capitalize()
0     Xiao ming
1    Xiao zhang
2           NaN
3      Sun quan
4       Guan yu
Name: name, dtype: object

title

每个单词的首字母大写;注意和capitalize的区别:

1
df["name"].str.title()
0     Xiao Ming
1    Xiao Zhang
2           NaN
3      Sun Quan
4       Guan Yu
Name: name, dtype: object

swapcase

大小写互换:小写换成大写,反之,大写换成小写

1
df["name"].str.swapcase()

原来的全部是小写,下面结果全部变成了大写:

0     XIAO MING
1    XIAO ZHANG
2           NaN
3      SUN QUAN
4       GUAN YU
Name: name, dtype: object
1
df["sex"].str.swapcase()
0      MALE
1    fEMALE
2    FEMALE
3    fEMALE
4      MALE
Name: sex, dtype: object

casefold

lower() 只对 ASCII 也就是 'A-Z’有效;此时casefold()和lower()相同效果

1
df["sex"].str.lower()
0      male
1    female
2    female
3    female
4      male
Name: sex, dtype: object
1
df["sex"].str.casefold()
0      male
1    female
2    female
3    female
4      male
Name: sex, dtype: object

但是其它一些语言里面存在小写的情况,lower()函数就不能处理。下面我们用德语中’ß’来区分二者,真实小写是’ss’:

1
2
s = 'ß'
s.lower()
'ß'

使用casefold函数能够实现:

1
s.casefold()
'ss'

在对 Series 中每个元素处理时,我们可以使用Pandas中内置的 map 或 apply 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
df["name"].apply(lambda x: x.upper())

# 结果

---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-14-8aacba359806> in <module>
----> 1 df["name"].apply(lambda x: x.upper())

/Applications/downloads/anaconda/anaconda3/lib/python3.7/site-packages/pandas/core/series.py in apply(self, func, convert_dtype, args, **kwds)
4136 else:
4137 values = self.astype(object)._values
-> 4138 mapped = lib.map_infer(values, f, convert=convert_dtype)
4139
4140 if len(mapped) and isinstance(mapped[0], Series):

pandas/_libs/lib.pyx in pandas._libs.lib.map_infer()

<ipython-input-14-8aacba359806> in <lambda>(x)
----> 1 df["name"].apply(lambda x: x.upper())

AttributeError: 'float' object has no attribute 'upper'

可以看到出现了报错:float类型的数据是没有upper属性的。这是因为数据中出现了NaN,NaN在Pandas中是被当做float类型。

下面使用upper方法来实现转换:当使用str.upper进行转换的时候能够自动排除缺失值的数据。

1
2
df["name"].str.upper()  # 写法1
df.name.str.upper() # 写法2
0     XIAO MING
1    XIAO ZHANG
2           NaN
3      SUN QUAN
4       GUAN YU
Name: name, dtype: object

去除空白符函数

空白符主要包括\n、\r、\t、’ ‘,即:换行、回车、制表符、空格等,用到3个常用的函数;

  • strip():用来去除头尾字符
  • lstrip():开头字符(左边)
  • rstrip():结尾字符(右边)

左右空白符

1
df["address"].str.strip()
0    广东省 深圳市
1    浙江省 杭州市
2     江苏省苏州市
3    福建省 泉州市
4     广东省广州市
Name: address, dtype: object
1
df["address"].str.strip().tolist()
['广东省 深圳市', '浙江省 杭州市', '江苏省苏州市', '福建省 泉州市', '广东省广州市']

左空白符

1
df["address"].str.lstrip().tolist()
['广东省 深圳市 ', '浙江省 杭州市', '江苏省苏州市 ', '福建省 泉州市', '广东省广州市']

右空白符

1
df["address"].str.rstrip().tolist()
[' 广东省 深圳市', '浙江省 杭州市', ' 江苏省苏州市', '福建省 泉州市', '广东省广州市']

对比Python自带函数

str.strip([chars):其中chars是可选的;

  • 如果没有的话就是默认删除空白符,\n、\t、空白符等

  • 如果给定的字符,当chars不为空时,函数会把chars解成一个个的字符,然后将这些字符去掉

1
2
s = " AB CD EF "
s
' AB CD EF '

下面是chars选项为空的时候:

1、删除左右两边的空白符

1
s.strip()
'AB CD EF'

2、删除左边的空白符

1
s.lstrip()
'AB CD EF '

3、删除右边的空白符

1
s.rstrip()
' AB CD EF'

当chars选项不为空的时候:

1
2
ss = "12AB C21D EF21"
ss
'12AB C21D EF21'

此时"12"字符串被拆解成两个字符12,然后单独去删除:

1
ss.strip("12")
'AB C21D EF'

删除左边的1或者2:

1
ss.lstrip("12")
'AB C21D EF21'

删除右边的1或者2

1
ss.rstrip("12")
'12AB C21D EF'

分割函数

split函数

1
2
3
4
5
6
Series.str.split(
pat=None, # 字符或正则表达式,默认是空白符
n=- 1, # 分割次数
expand=False, # 是否扩展
regex=None # 决定传入模式是否为正则
)

关于参数regex的解释(版本1.4.0开始出现的):

  • True:默认是正则
  • False:默认是普通字符
  • None and pat length is 1:普通字符
  • None and pat length is not 1:正则表达式

注意:当传入的是正则表达式的时候,不能设置成False

1
df["name"].str.split()  # 默认空白符分割
0     [xiao, ming]
1    [xiao, zhang]
2              NaN
3      [sun, quan]
4       [guan, yu]
Name: name, dtype: object
1
df["name"].str.split(" ")
0     [xiao, ming]
1    [xiao, zhang]
2              NaN
3      [sun, quan]
4       [guan, yu]
Name: name, dtype: object

指定非空的分割符号:

1
df["sex"].str.split("a")  # 指定分隔符
0      [m, le]
1    [Fem, le]
2    [fem, le]
3    [Fem, le]
4      [m, le]
Name: sex, dtype: object

将分割的结果进行扩展,生成的是DataFrame:

1
df["name"].str.split(expand=True)
0 1
0 xiao ming
1 xiao zhang
2 NaN NaN
3 sun quan
4 guan yu

通过 get 函数或者[]来访问切割后的结果:

1
df["name"].str.split(expand=True).get(1)
0     ming
1    zhang
2      NaN
3     quan
4       yu
Name: 1, dtype: object
1
df["name"].str.split(expand=True)[1]
0     ming
1    zhang
2      NaN
3     quan
4       yu
Name: 1, dtype: object

rsplit函数

1
df["sex"].str.rsplit("a")  # 指定分隔符
0      [m, le]
1    [Fem, le]
2    [fem, le]
3    [Fem, le]
4      [m, le]
Name: sex, dtype: object
1
df["sex"].str.rsplit("f")  # 指定分隔符
0       [male]
1     [Female]
2    [, emale]
3     [Female]
4       [male]
Name: sex, dtype: object

如何理解分割次数n

1
2
s3 = pd.Series("abcdabcab")
s3
0    abcdabcab
dtype: object

通过字符b来进行切割,默认参数下:

1
s3.str.rsplit("b")
0    [a, cda, ca, ]
dtype: object

切割的最大次数为2,生成3个元素:

1
s3.str.split("b",n=2)
0    [a, cda, cab]
dtype: object

指定切割3次后的结果:

1
s3.str.split("b",n=3)
0    [a, cda, ca, ]
dtype: object

最大的切割次数是3,下面切割4次和3次的效果相同:

1
s3.str.split("b",n=4)
0    [a, cda, ca, ]
dtype: object

n=-1表示切割的最大次数,默认情况:

1
s3.str.split("b",n=-1)
0    [a, cda, ca, ]
dtype: object

本文标题:Pandas处理文本的3大秘诀

发布时间:2022年03月04日 - 13:03

原始链接:http://www.renpeter.cn/2022/03/04/Pandas%E5%A4%84%E7%90%86%E6%96%87%E6%9C%AC%E7%9A%843%E5%A4%A7%E7%A7%98%E8%AF%80.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Coffee or Tea