处理文本数据#
文本数据类型#
在 pandas 中存储文本数据有两种方法:
object-dtype NumPy 数组。StringDtype扩展类型。
我们建议使用 StringDtype 来存储文本数据。
在 pandas 1.0 之前,object dtype 是唯一的选择。这在很多方面都令人不快:
您可能会意外地在
objectdtype 数组中存储字符串和非字符串的*混合*。拥有一个专门的 dtype 会更好。objectdtype 会破坏特定于 dtype 的操作,例如DataFrame.select_dtypes()。无法清楚地选择*仅*文本列,同时排除仍然是 object dtype 的非文本列。在阅读代码时,
objectdtype 数组的内容不如'string'清楚。
目前,包含字符串的 object dtype 数组和 arrays.StringArray 的性能大致相同。我们预计未来的增强功能将显着提高 StringArray 的性能并降低其内存开销。
警告
StringArray 目前仍被视为实验性的。其实现和部分 API 可能会在不发出警告的情况下进行更改。
为了向后兼容,object dtype 仍然是我们推断字符串列表的默认类型
要显式请求 string dtype,请指定 dtype
或者在创建 Series 或 DataFrame 后使用 astype
您还可以使用 StringDtype "string" 作为非字符串数据的 dtype,它将被转换为 string dtype:
或者从现有的 pandas 数据转换:
行为差异#
这些是 StringDtype 对象行为与 object dtype 不同的地方
对于
StringDtype,返回**数值**输出的 string accessor methods 将始终返回可为空的整数 dtype,而不是根据 NA 值是否存在而返回 int 或 float dtype。返回**布尔值**输出的方法将返回可为空的布尔 dtype。输出均为
Int64dtype。与 object-dtype 相比:当存在 NA 值时,输出 dtype 为 float64。对于返回布尔值的类似方法也是如此。
某些字符串方法,例如
Series.str.decode(),在StringArray上不可用,因为StringArray只保存字符串,而不是字节。在比较运算中,
arrays.StringArray和由StringArray支持的Series将返回带有BooleanDtype的对象,而不是booldtype 对象。StringArray中的缺失值将在比较运算中传播,而不是像numpy.nan那样总是比较不等。
本文档其余部分的其他内容同样适用于 string 和 object dtype。
字符串方法#
Series 和 Index 都配备了一组字符串处理方法,可以轻松地对数组的每个元素进行操作。也许最重要的是,这些方法会自动排除缺失/NA 值。这些方法通过 str 属性访问,并且通常具有与等效的(标量)内置字符串方法相同的名称:
Index 上的字符串方法在清理或转换 DataFrame 列时特别有用。例如,您可能有名为“ Leading or trailing whitespace”的列:
由于 df.columns 是一个 Index 对象,我们可以使用 .str 访问器
然后可以使用这些字符串方法按需清理列。这里我们正在删除前导和尾随空格,将所有名称转换为小写,并将任何剩余的空格替换为下划线:
备注
如果您的 Series 中有许多重复的元素(即 Series 中唯一元素的数量远小于 Series 的长度),则可以更快地将原始 Series 转换为 category 类型,然后在其上使用 .str.<method> 或 .dt.<property>。性能差异来自于这样一个事实:对于 category 类型的 Series,字符串操作是在 .categories 上执行的,而不是在 Series 的每个元素上执行的。
请注意,具有字符串 .categories 的 category 类型 Series 在某些方面与字符串类型的 Series 存在局限性(例如,您不能将字符串相加:如果 s 是 category 类型的 Series,则 s + " " + s 将不起作用)。此外,在处理类型为 list 的元素时,此类 Series 不提供 .str 方法。
警告
Series 的类型会被推断出来,并且只允许使用字符串类型。
一般来说,.str 访问器仅用于字符串。除了极少数例外,其他用法不被支持,并且将来可能会被禁用。
拆分和替换字符串#
像 split 这样的方法会返回一个 Series 的列表:
可以使用 get 或 [] 符号来访问拆分列表中的元素:
使用 expand 可以轻松地将其展开以返回一个 DataFrame。
当原始 Series 具有 StringDtype 时,输出列也将全部是 StringDtype 。
也可以限制拆分的次数:
rsplit 与 split 类似,只是它沿着反方向工作,即从字符串末尾到字符串开头:
replace 可选地使用 regular expressions :
在 2.0 版本发生变更.
带 regex=True 的单字符模式也将被视为正则表达式:
如果您想进行字面字符串替换(等同于 str.replace() ),您可以将可选的 regex 参数设置为 False,而不是转义每个字符。在这种情况下,pat 和 repl 都必须是字符串:
replace 方法也可以接受一个可调用对象作为替换。它使用 re.sub() 对每个 pat 调用。可调用对象应该接受一个位置参数(一个正则表达式对象)并返回一个字符串。
replace 方法还接受来自 re.compile() 的已编译正则表达式对象作为模式。所有标志都应包含在已编译的正则表达式对象中。
当使用已编译的正则表达式对象调用 replace 时包含 flags 参数将引发 ValueError。
removeprefix 和 removesuffix 的效果与 Python 3.9 中添加的 str.removeprefix 和 str.removesuffix <https://docs.python.org/3/library/stdtypes.html#str.removeprefix>`__ 相同:
在 1.4.0 版本加入.
连接#
有几种方法可以将 Series 或 Index 与自身或其他对象连接起来,它们都基于 cat() 或 ``Index.str.cat`。
将单个 Series 连接成一个字符串#
可以连接 Series``(或 ``Index)的内容:
如果未指定,分隔符的关键字 sep 默认为空字符串 sep='':
默认情况下,会忽略缺失值。使用 na_rep,可以为它们指定表示:
将 Series 和类似列表的对象连接成一个 Series#
cat() 的第一个参数可以是类似列表的对象,前提是它的长度与调用它的 Series``(或 ``Index)匹配。
任何一方的缺失值都会导致结果中出现缺失值,除非 指定了 na_rep:
将 Series 和类数组的对象连接成一个 Series#
参数 others 也可以是二维的。在这种情况下,行数必须与调用方的 Series``(或 ``Index)的长度匹配。
将 Series 和带索引的对象连接成一个 Series,并进行对齐#
通过设置 join 关键字,可以对 Series 或 DataFrame 进行索引对齐后再进行连接。
join 可用选项(’left’, ‘outer’, ‘inner’, ‘right’ 之一)都可以使用。特别是,对齐也意味着不同长度的索引不需要再完全匹配。
当 others 是 DataFrame 时,也可以使用相同的对齐方式:
将 Series 和多个对象连接成一个 Series#
可以将在类列表容器(包括迭代器、dict 视图等)中的多个类数组项(特别是:Series、Index 和 ``np.ndarray` 的一维变体)组合起来。
传入列表中的所有无索引元素(例如 np.ndarray)必须与调用方的 Series``(或 ``Index)长度匹配,但 Series 和 Index 可以具有任意长度(只要通过 join=None 禁用了对齐):
如果对包含不同索引的类列表 others 使用 join='right',则这些索引的并集将用作最终连接的基础:
使用 .str 进行索引#
您可以使用 [] 表示法按位置直接索引。如果索引超出了字符串的末尾,结果将是 NaN。
提取子字符串#
提取每个主题的第一个匹配项 (extract)#
The extract method accepts a regular expression with at least one
capture group.
提取包含多个捕获组的正则表达式会返回一个 DataFrame,每个捕获组占一列。
不匹配的元素将返回一个全为 NaN 的行。因此,一个包含杂乱字符串的 Series 可以被“转换”为一个具有相同索引的 Series 或 DataFrame,其中包含已清理或更有用的字符串,而无需使用 get() 来访问元组或 re.match 对象。结果的 dtype 始终是 object,即使没有找到匹配项并且结果只包含 NaN。
可以使用形如
的命名捕获组和可选捕获组。请注意,正则表达式中的任何捕获组名称都将用作列名;否则将使用捕获组编号。
也可以使用。请注意,正则表达式中的任何捕获组名称都将用作列名;否则捕获组编号将用作列名。
提取包含单个捕获组的正则表达式会返回一个 DataFrame,如果 expand=True,则只有一列。
如果 expand=False,则返回一个 Series。
在一个 Index 上使用包含恰好一个捕获组的正则表达式调用会返回一个 DataFrame,如果 expand=True,则只有一列。
如果 expand=False,则返回一个 Index。
在一个 Index 上使用包含多个捕获组的正则表达式调用会返回一个 DataFrame,如果 expand=True。
如果 expand=False,则引发 ValueError。
下表总结了 extract(expand=False) 的行为(第一列是输入主题,第一行是正则表达式的组数)
1 组 |
>1 组 |
|
Index |
Index |
ValueError |
Series |
Series |
DataFrame |
提取每个主题的所有匹配项 (extractall)#
与 ``extract``(只返回第一个匹配项)不同,
extractall 方法返回每个匹配项。extractall 的结果始终是一个 DataFrame,其行具有 MultiIndex。MultiIndex 的最后一级命名为 match,并指示主题中的顺序。
当 Series 中的每个主题字符串只有一个匹配项时,
则 extractall(pat).xs(0, level='match') 与 extract(pat) 的结果相同。
Index 也支持 .str.extractall。它返回一个 DataFrame,其结果与具有默认索引(从 0 开始)的 Series.str.extractall 相同。
测试与模式匹配或包含模式的字符串#
您可以检查元素是否包含某个模式:
或者元素是否匹配某个模式:
备注
match、fullmatch 和 contains 之间的区别在于严格程度:“fullmatch 测试整个字符串是否与正则表达式匹配;match 测试正则表达式是否与字符串的第一个字符匹配;contains 测试正则表达式是否与字符串中的任何位置匹配。
re 包中这三种匹配模式对应的函数分别是 re.fullmatch 、re.match 和 re.search 。
match、fullmatch、contains、startswith 和 endswith 等方法接受一个额外的 na 参数,因此可以将被视为 True 或 False 的缺失值:
创建指示变量#
您可以从字符串列中提取虚拟变量。例如,如果它们由 '|' 分隔:
字符串 Index 也支持 get_dummies,它返回一个 MultiIndex。
另请参阅 get_dummies() 。
方法摘要#
方法 |
描述 |
|---|---|
连接字符串 |
|
按分隔符分割字符串 |
|
从字符串末尾开始按分隔符分割字符串 |
|
索引到每个元素(检索第 i 个元素) |
|
使用传入的分隔符连接 Series 中每个元素中的字符串 |
|
按分隔符分割字符串,返回虚拟变量的 DataFrame |
|
如果每个字符串包含模式/正则表达式,则返回布尔数组 |
|
将模式/正则表达式/字符串的出现替换为其他字符串或给定出现的调用返回的结果 |
|
删除字符串中的前缀,即仅当字符串以指定前缀开头时才删除。 |
|
删除字符串中的后缀,即仅当字符串以指定后缀结尾时才删除。 |
|
重复值( |
|
在字符串两侧添加空白 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
将长字符串分割成宽度小于给定宽度的行 |
|
对 Series 中的每个字符串进行切片 |
|
用提供的值替换每个字符串中的切片 |
|
计算模式出现的次数 |
|
对于每个元素,等同于 |
|
对于每个元素,等同于 |
|
计算每个字符串中模式/正则表达式的所有出现次数列表 |
|
对每个元素调用 |
|
对每个元素调用 |
|
对每个元素调用 |
|
计算字符串长度 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
返回 Unicode NORM 形式。等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |
|
等同于 |