提取子字符串

提取第一个匹配的对象 (extract)

警告

在 0.18.0中,extract 拥有了 expand 参数。当 expand=False时, 将返回一个序列,索引或者数据表, 这取决于原对象和正则表达式(之前的版本也是如此)。当 expand=True 时,它则总是返回一个``DataFrame``,这样可以更加一致,并且减少用户的混淆。 ``Expand=True`` 从0.23.0版本之后成为默认值。

extract 方法接受一个至少含有一个捕获组的 正则表达式

使用超过一个捕获组的正则表达式则会提取并返回一个数据表,每一列为一个捕获组。

  1. In [79]: pd.Series(['a1', 'b2', 'c3']).str.extract('([ab])(\d)', expand=False)
  2. Out[79]:
  3. 0 1
  4. 0 a 1
  5. 1 b 2
  6. 2 NaN NaN

没有成功匹配的元素将会返回一行NaN。因此,一个序列的混乱的字符串可以被‘转换’为一个类似索引的序列或数据表。返回的内容会更为清爽,而且不需要使用get()方法来访问元组中的成员或者re.match对象。返回的类型将总是object类,即使匹配失败,返回的全是NaN

有名称的捕获组,如:

  1. In [80]: pd.Series(['a1', 'b2', 'c3']).str.extract('(?P<letter>[ab])(?P<digit>\d)', expand=False)
  2. Out[80]:
  3. letter digit
  4. 0 a 1
  5. 1 b 2
  6. 2 NaN NaN

可选组类似,如:

  1. In [81]: pd.Series(['a1', 'b2', '3']).str.extract('([ab])?(\d)', expand=False)
  2. Out[81]:
  3. 0 1
  4. 0 a 1
  5. 1 b 2
  6. 2 NaN 3

也可以被使用。注意,任何有名称的捕获组,其名称都会被用做列名,否则将会直接使用数字

如果仅使用正则表达式捕获一个组,而expand=True,那么仍然将返回一个数据表。

  1. In [82]: pd.Series(['a1', 'b2', 'c3']).str.extract('[ab](\d)', expand=True)
  2. Out[82]:
  3. 0
  4. 0 1
  5. 1 2
  6. 2 NaN

如果expand=False,则会返回一个序列。

  1. In [83]: pd.Series(['a1', 'b2', 'c3']).str.extract('[ab](\d)', expand=False)
  2. Out[83]:
  3. 0 1
  4. 1 2
  5. 2 NaN
  6. dtype: object

在索引上使用正则表达式,并且仅捕获一个组时,将会返回一个数据表,如果expand=True

  1. In [84]: s = pd.Series(["a1", "b2", "c3"], ["A11", "B22", "C33"])
  2. In [85]: s
  3. Out[85]:
  4. A11 a1
  5. B22 b2
  6. C33 c3
  7. dtype: object
  8. In [86]: s.index.str.extract("(?P<letter>[a-zA-Z])", expand=True)
  9. Out[86]:
  10. letter
  11. 0 A
  12. 1 B
  13. 2 C

如果expand=False,则返回一个Index

  1. In [87]: s.index.str.extract("(?P<letter>[a-zA-Z])", expand=False)
  2. Out[87]: Index(['A', 'B', 'C'], dtype='object', name='letter')

如果在索引上使用正则并捕获多个组,则返回一个数据表,如果expand=True

  1. In [88]: s.index.str.extract("(?P<letter>[a-zA-Z])([0-9]+)", expand=True)
  2. Out[88]:
  3. letter 1
  4. 0 A 11
  5. 1 B 22
  6. 2 C 33

如果 expand=False,则抛出ValueError

  1. >>> s.index.str.extract("(?P<letter>[a-zA-Z])([0-9]+)", expand=False)
  2. ValueError: only one regex group is supported with Index

下面的表格总结了extract (expand=False)时的行为(输入对象在第一列,捕获组的数量在第一行)

  • | 1 group | >1 group Index | Index | ValueError Series | Series | DataFrame

提取所有的匹配 (extractall)

New in version 0.18.0.

不同于 extract(只返回第一个匹配),

  1. In [89]: s = pd.Series(["a1a2", "b1", "c1"], index=["A", "B", "C"])
  2. In [90]: s
  3. Out[90]:
  4. A a1a2
  5. B b1
  6. C c1
  7. dtype: object
  8. In [91]: two_groups = '(?P<letter>[a-z])(?P<digit>[0-9])'
  9. In [92]: s.str.extract(two_groups, expand=True)
  10. Out[92]:
  11. letter digit
  12. A a 1
  13. B b 1
  14. C c 1

··extractall方法返回所有的匹配。extractall总是返回一个带有行多重索引的数据表,最后一级被命名为match,它指出匹配的顺序

  1. In [93]: s.str.extractall(two_groups)
  2. Out[93]:
  3. letter digit
  4. match
  5. A 0 a 1
  6. 1 a 2
  7. B 0 b 1
  8. C 0 c 1

当所有的对象字串都只有一个匹配时,

  1. In [94]: s = pd.Series(['a3', 'b3', 'c2'])
  2. In [95]: s
  3. Out[95]:
  4. 0 a3
  5. 1 b3
  6. 2 c2
  7. dtype: object

extractall(pat).xs(0, level='match') 的返回与extract(pat)相同。

  1. In [96]: extract_result = s.str.extract(two_groups, expand=True)
  2. In [97]: extract_result
  3. Out[97]:
  4. letter digit
  5. 0 a 3
  6. 1 b 3
  7. 2 c 2
  8. In [98]: extractall_result = s.str.extractall(two_groups)
  9. In [99]: extractall_result
  10. Out[99]:
  11. letter digit
  12. match
  13. 0 0 a 3
  14. 1 0 b 3
  15. 2 0 c 2
  16. In [100]: extractall_result.xs(0, level="match")
  17. Out[100]:
  18. letter digit
  19. 0 a 3
  20. 1 b 3
  21. 2 c 2

索引也支持.str.extractall。 它返回一个数据表,其中包含与Series.str.estractall相同的结果,使用默认索引(从0开始)

New in version 0.19.0.

  1. In [101]: pd.Index(["a1a2", "b1", "c1"]).str.extractall(two_groups)
  2. Out[101]:
  3. letter digit
  4. match
  5. 0 0 a 1
  6. 1 a 2
  7. 1 0 b 1
  8. 2 0 c 1
  9. In [102]: pd.Series(["a1a2", "b1", "c1"]).str.extractall(two_groups)
  10. Out[102]:
  11. letter digit
  12. match
  13. 0 0 a 1
  14. 1 a 2
  15. 1 0 b 1
  16. 2 0 c 1