使用文本数据#

文本数据类型#

1.0.0 新版功能.

在Pandas中存储文本数据有两种方式:

  1. object -dtype NumPy数组。

  2. StringDtype 扩展类型。

我们建议您使用 StringDtype 来存储文本数据。

在Pandas1.0之前, object Dtype是唯一的选择。这是不幸的,原因有很多:

  1. 您可能会意外地存储一个 混合物 中的字符串和非字符串的 object 数据类型数组。最好是有一个专用的dtype。

  2. object Dtype中断了特定于Dtype的操作,如 DataFrame.select_dtypes() 。没有一个明确的方法来选择 just 文本,同时排除非文本但仍为对象数据类型的列。

  3. 在读取代码时, object 数据类型数组不太清楚 'string'

目前,该系统的性能 object 字符串的数据类型数组和 arrays.StringArray 几乎是一样的。我们预计未来的增强功能将显著提高性能并降低 StringArray

警告

StringArray 目前被认为是试验性的。API的实现和部分内容可能会在没有任何警告的情况下发生更改。

为了向后兼容, object Dtype仍然是我们推断的字符串列表的默认类型

In [1]: pd.Series(["a", "b", "c"])
Out[1]: 
0    a
1    b
2    c
dtype: object

显式请求 string Dtype,则指定 dtype

In [2]: pd.Series(["a", "b", "c"], dtype="string")
Out[2]: 
0    a
1    b
2    c
dtype: string

In [3]: pd.Series(["a", "b", "c"], dtype=pd.StringDtype())
Out[3]: 
0    a
1    b
2    c
dtype: string

astypeSeriesDataFrame 已创建

In [4]: s = pd.Series(["a", "b", "c"])

In [5]: s
Out[5]: 
0    a
1    b
2    c
dtype: object

In [6]: s.astype("string")
Out[6]: 
0    a
1    b
2    c
dtype: string

在 1.1.0 版更改.

您还可以使用 StringDtype /“字符串”``作为非字符串数据的数据类型,它将被转换为 ``string 数据类型:

In [7]: s = pd.Series(["a", 2, np.nan], dtype="string")

In [8]: s
Out[8]: 
0       a
1       2
2    <NA>
dtype: string

In [9]: type(s[1])
Out[9]: str

或从现有的Pandas数据转换:

In [10]: s1 = pd.Series([1, 2, np.nan], dtype="Int64")

In [11]: s1
Out[11]: 
0       1
1       2
2    <NA>
dtype: Int64

In [12]: s2 = s1.astype("string")

In [13]: s2
Out[13]: 
0       1
1       2
2    <NA>
dtype: string

In [14]: type(s2[0])
Out[14]: str

行为差异#

在这些地方, StringDtype 对象不同于 object 数据类型

  1. StringDtypestring accessor methods 那就是回报 数字 输出将始终返回可为空的整型数据类型,而不是整型或浮点型数据类型,具体取决于NA值的存在。方法返回 布尔值 输出将返回一个可以为空的布尔数据类型。

    In [15]: s = pd.Series(["a", None, "b"], dtype="string")
    
    In [16]: s
    Out[16]: 
    0       a
    1    <NA>
    2       b
    dtype: string
    
    In [17]: s.str.count("a")
    Out[17]: 
    0       1
    1    <NA>
    2       0
    dtype: Int64
    
    In [18]: s.dropna().str.count("a")
    Out[18]: 
    0    1
    2    0
    dtype: Int64
    

    这两个输出都是 Int64 数据类型。将其与对象数据类型进行比较

    In [19]: s2 = pd.Series(["a", None, "b"], dtype="object")
    
    In [20]: s2.str.count("a")
    Out[20]: 
    0    1.0
    1    NaN
    2    0.0
    dtype: float64
    
    In [21]: s2.dropna().str.count("a")
    Out[21]: 
    0    1
    2    0
    dtype: int64
    

    如果存在NA值,则输出数据类型为Float64。返回布尔值的方法也是如此。

    In [22]: s.str.isdigit()
    Out[22]: 
    0    False
    1     <NA>
    2    False
    dtype: boolean
    
    In [23]: s.str.match("a")
    Out[23]: 
    0     True
    1     <NA>
    2    False
    dtype: boolean
    
  1. 一些字符串方法,如 Series.str.decode() 在上不可用 StringArray 因为 StringArray 只保存字符串,不保存字节。

  2. 在比较运算中, arrays.StringArraySeries 背后有一个 StringArray 将返回一个具有 BooleanDtype ,而不是 bool 数据类型对象。中缺少值 StringArray 将在比较运算中传播,而不是总是比较不相等的 numpy.nan

本文档其余部分中的其他内容同样适用于 stringobject 数据类型。

字符串方法#

Series和Index配备了一组字符串处理方法,使您可以轻松地对数组的每个元素进行操作。也许最重要的是,这些方法会自动排除丢失的/NA值。这些都可以通过 str 属性,并且通常具有与等价(标量)内置字符串方法匹配的名称:

In [24]: s = pd.Series(
   ....:     ["A", "B", "C", "Aaba", "Baca", np.nan, "CABA", "dog", "cat"], dtype="string"
   ....: )
   ....: 

In [25]: s.str.lower()
Out[25]: 
0       a
1       b
2       c
3    aaba
4    baca
5    <NA>
6    caba
7     dog
8     cat
dtype: string

In [26]: s.str.upper()
Out[26]: 
0       A
1       B
2       C
3    AABA
4    BACA
5    <NA>
6    CABA
7     DOG
8     CAT
dtype: string

In [27]: s.str.len()
Out[27]: 
0       1
1       1
2       1
3       4
4       4
5    <NA>
6       4
7       3
8       3
dtype: Int64
In [28]: idx = pd.Index([" jack", "jill ", " jesse ", "frank"])

In [29]: idx.str.strip()
Out[29]: Index(['jack', 'jill', 'jesse', 'frank'], dtype='object')

In [30]: idx.str.lstrip()
Out[30]: Index(['jack', 'jill ', 'jesse ', 'frank'], dtype='object')

In [31]: idx.str.rstrip()
Out[31]: Index([' jack', 'jill', ' jesse', 'frank'], dtype='object')

Index上的字符串方法对于清理或转换DataFrame列特别有用。例如,您可能具有前导空格或尾随空格的列:

In [32]: df = pd.DataFrame(
   ....:     np.random.randn(3, 2), columns=[" Column A ", " Column B "], index=range(3)
   ....: )
   ....: 

In [33]: df
Out[33]: 
    Column A    Column B 
0    0.469112   -0.282863
1   -1.509059   -1.135632
2    1.212112   -0.173215

因为 df.columns 是一个Index对象,我们可以使用 .str 访问者

In [34]: df.columns.str.strip()
Out[34]: Index(['Column A', 'Column B'], dtype='object')

In [35]: df.columns.str.lower()
Out[35]: Index([' column a ', ' column b '], dtype='object')

然后,可以根据需要使用这些字符串方法来清理列。在这里,我们删除前导空格和尾随空格,将所有名称小写,并将剩余的空格替换为下划线:

In [36]: df.columns = df.columns.str.strip().str.lower().str.replace(" ", "_")

In [37]: df
Out[37]: 
   column_a  column_b
0  0.469112 -0.282863
1 -1.509059 -1.135632
2  1.212112 -0.173215

备注

如果你有一个 Series 其中重复了大量元素(即 Series 的长度远远小于 Series ),它可以更快地转换原始的 Series 到一种类型 category 然后使用 .str.<method>.dt.<property> 就在那上面。性能差异来自于这样一个事实,即 Series 类型的 category ,字符串操作是在 .categories 而不是在 Series

请注意,a Series 类型的 category 带字符串 .categories 与以下内容相比有一些局限性 Series 字符串类型(例如,您不能将字符串彼此相加: s + " " + s 如果出现以下情况,则不会起作用 s 是一种 Series 类型的 category )。另外, .str 类型的元素上操作的方法 list 在这种情况下不可用 Series

警告

在v.0.25.0之前, .str -存取器只执行最基本的类型检查。从v.0.25.0开始,将推断系列的类型,并更严格地强制执行允许的类型(即字符串)。

一般说来, .str 访问器仅适用于字符串。除极少数例外情况外,其他用途不受支持,并可能在以后禁用。

拆分和替换字符串#

像这样的方法 split 返回一系列列表:

In [38]: s2 = pd.Series(["a_b_c", "c_d_e", np.nan, "f_g_h"], dtype="string")

In [39]: s2.str.split("_")
Out[39]: 
0    [a, b, c]
1    [c, d, e]
2         <NA>
3    [f, g, h]
dtype: object

拆分列表中的元素可以使用 get[] 记号:

In [40]: s2.str.split("_").str.get(1)
Out[40]: 
0       b
1       d
2    <NA>
3       g
dtype: object

In [41]: s2.str.split("_").str[1]
Out[41]: 
0       b
1       d
2    <NA>
3       g
dtype: object

将其扩展为返回DataFrame非常容易,方法是使用 expand

In [42]: s2.str.split("_", expand=True)
Out[42]: 
      0     1     2
0     a     b     c
1     c     d     e
2  <NA>  <NA>  <NA>
3     f     g     h

原创时 SeriesStringDtype ,则输出列将全部为 StringDtype 也是。

还可以限制拆分的数量:

In [43]: s2.str.split("_", expand=True, n=1)
Out[43]: 
      0     1
0     a   b_c
1     c   d_e
2  <NA>  <NA>
3     f   g_h

rsplit 类似于 split 除非它以相反的方向工作,即从字符串的末尾到字符串的开头:

In [44]: s2.str.rsplit("_", expand=True, n=1)
Out[44]: 
      0     1
0   a_b     c
1   c_d     e
2  <NA>  <NA>
3   f_g     h

replace optionally uses regular expressions

In [45]: s3 = pd.Series(
   ....:     ["A", "B", "C", "Aaba", "Baca", "", np.nan, "CABA", "dog", "cat"],
   ....:     dtype="string",
   ....: )
   ....: 

In [46]: s3
Out[46]: 
0       A
1       B
2       C
3    Aaba
4    Baca
5        
6    <NA>
7    CABA
8     dog
9     cat
dtype: string

In [47]: s3.str.replace("^.a|dog", "XX-XX ", case=False, regex=True)
Out[47]: 
0           A
1           B
2           C
3    XX-XX ba
4    XX-XX ca
5            
6        <NA>
7    XX-XX BA
8      XX-XX 
9     XX-XX t
dtype: string

警告

在处理正则表达式时必须小心!当前的行为是将单字符模式视为文字字符串,即使在 regex 设置为 True 。此行为已弃用,并将在未来版本中删除,以便 regex 关键字始终受到尊重。

在 1.2.0 版更改.

如果想要字符串的原义替换(等效于 str.replace() ),您可以设置可选的 regex 参数设置为 False ,而不是转义每个字符。在这种情况下,两者都 patrepl 必须是字符串:

In [48]: dollars = pd.Series(["12", "-$10", "$10,000"], dtype="string")

# These lines are equivalent
In [49]: dollars.str.replace(r"-\$", "-", regex=True)
Out[49]: 
0         12
1        -10
2    $10,000
dtype: string

In [50]: dollars.str.replace("-$", "-", regex=False)
Out[50]: 
0         12
1        -10
2    $10,000
dtype: string

这个 replace 方法也可以使用Callable作为替换。它在每一个 pat 使用 re.sub() 。Callable应该有一个位置参数(regex对象)并返回一个字符串。

# Reverse every lowercase alphabetic word
In [51]: pat = r"[a-z]+"

In [52]: def repl(m):
   ....:     return m.group(0)[::-1]
   ....: 

In [53]: pd.Series(["foo 123", "bar baz", np.nan], dtype="string").str.replace(
   ....:     pat, repl, regex=True
   ....: )
   ....: 
Out[53]: 
0    oof 123
1    rab zab
2       <NA>
dtype: string

# Using regex groups
In [54]: pat = r"(?P<one>\w+) (?P<two>\w+) (?P<three>\w+)"

In [55]: def repl(m):
   ....:     return m.group("two").swapcase()
   ....: 

In [56]: pd.Series(["Foo Bar Baz", np.nan], dtype="string").str.replace(
   ....:     pat, repl, regex=True
   ....: )
   ....: 
Out[56]: 
0     bAR
1    <NA>
dtype: string

这个 replace 方法还接受来自 re.compile() 作为一种模式。所有标志都应包含在已编译的正则表达式对象中。

In [57]: import re

In [58]: regex_pat = re.compile(r"^.a|dog", flags=re.IGNORECASE)

In [59]: s3.str.replace(regex_pat, "XX-XX ", regex=True)
Out[59]: 
0           A
1           B
2           C
3    XX-XX ba
4    XX-XX ca
5            
6        <NA>
7    XX-XX BA
8      XX-XX 
9     XX-XX t
dtype: string

包括一个 flags 参数时调用 replace 使用已编译的正则表达式对象将引发 ValueError

In [60]: s3.str.replace(regex_pat, 'XX-XX ', flags=re.IGNORECASE)
---------------------------------------------------------------------------
ValueError: case and flags cannot be set when pat is a compiled regex

removeprefix and removesuffix have the same effect as str.removeprefix and str.removesuffix added in Python 3.9 <https://docs.python.org/3/library/stdtypes.html#str.removeprefix>`__ :

1.4.0 新版功能.

In [61]: s = pd.Series(["str_foo", "str_bar", "no_prefix"])

In [62]: s.str.removeprefix("str_")
Out[62]: 
0          foo
1          bar
2    no_prefix
dtype: object

In [63]: s = pd.Series(["foo_str", "bar_str", "no_suffix"])

In [64]: s.str.removesuffix("_str")
Out[64]: 
0          foo
1          bar
2    no_suffix
dtype: object

串接#

有几种方法可以将 SeriesIndex ,无论是与自身还是与其他人一起,都基于 cat() ,分别为: Index.str.cat

将单个系列连接成一个字符串#

的内容。 Series (或 Index )可以连接在一起:

In [65]: s = pd.Series(["a", "b", "c", "d"], dtype="string")

In [66]: s.str.cat(sep=",")
Out[66]: 'a,b,c,d'

如果未指定,则关键字 sep 对于默认为空字符串的分隔符, sep=''

In [67]: s.str.cat()
Out[67]: 'abcd'

默认情况下,将忽略缺少的值。vbl.使用 na_rep ,可以为他们提供一个代表:

In [68]: t = pd.Series(["a", "b", np.nan, "d"], dtype="string")

In [69]: t.str.cat(sep=",")
Out[69]: 'a,b,d'

In [70]: t.str.cat(sep=",", na_rep="-")
Out[70]: 'a,b,-,d'

将一个系列和类似列表的东西连接成一个系列#

的第一个参数 cat() 可以是类似列表的对象,只要它与调用的长度匹配 Series (或 Index )。

In [71]: s.str.cat(["A", "B", "C", "D"])
Out[71]: 
0    aA
1    bB
2    cC
3    dD
dtype: string

任何一侧的缺失值都将导致结果中的缺失值, 除非 na_rep 已指定:

In [72]: s.str.cat(t)
Out[72]: 
0      aa
1      bb
2    <NA>
3      dd
dtype: string

In [73]: s.str.cat(t, na_rep="-")
Out[73]: 
0    aa
1    bb
2    c-
3    dd
dtype: string

将一个级数和类似数组的东西连接成一个级数#

该参数 others 也可以是二维的。在这种情况下,号码或行数必须与呼叫的长度匹配 Series (或 Index )。

In [74]: d = pd.concat([t, s], axis=1)

In [75]: s
Out[75]: 
0    a
1    b
2    c
3    d
dtype: string

In [76]: d
Out[76]: 
      0  1
0     a  a
1     b  b
2  <NA>  c
3     d  d

In [77]: s.str.cat(d, na_rep="-")
Out[77]: 
0    aaa
1    bbb
2    c-c
3    ddd
dtype: string

将序列和索引对象连接成序列,并对齐#

用于与 SeriesDataFrame 属性,可以在连接前对齐索引。 join -关键字。

In [78]: u = pd.Series(["b", "d", "a", "c"], index=[1, 3, 0, 2], dtype="string")

In [79]: s
Out[79]: 
0    a
1    b
2    c
3    d
dtype: string

In [80]: u
Out[80]: 
1    b
3    d
0    a
2    c
dtype: string

In [81]: s.str.cat(u)
Out[81]: 
0    aa
1    bb
2    cc
3    dd
dtype: string

In [82]: s.str.cat(u, join="left")
Out[82]: 
0    aa
1    bb
2    cc
3    dd
dtype: string

警告

如果 join 关键字未传递,则该方法 cat() 当前将回退到0.23.0版之前的行为(即无对齐),但 FutureWarning 如果涉及的任何索引不同,则将引发,因为此默认值将更改为 join='left' 在未来的版本中。

通常的选项可用于 join (其中一项 'left', 'outer', 'inner', 'right' )。特别是,对齐还意味着不同的长度不再需要重合。

In [83]: v = pd.Series(["z", "a", "b", "d", "e"], index=[-1, 0, 1, 3, 4], dtype="string")

In [84]: s
Out[84]: 
0    a
1    b
2    c
3    d
dtype: string

In [85]: v
Out[85]: 
-1    z
 0    a
 1    b
 3    d
 4    e
dtype: string

In [86]: s.str.cat(v, join="left", na_rep="-")
Out[86]: 
0    aa
1    bb
2    c-
3    dd
dtype: string

In [87]: s.str.cat(v, join="outer", na_rep="-")
Out[87]: 
-1    -z
 0    aa
 1    bb
 2    c-
 3    dd
 4    -e
dtype: string

在以下情况下可以使用相同的对齐方式 others 是一种 DataFrame

In [88]: f = d.loc[[3, 2, 1, 0], :]

In [89]: s
Out[89]: 
0    a
1    b
2    c
3    d
dtype: string

In [90]: f
Out[90]: 
      0  1
3     d  d
2  <NA>  c
1     b  b
0     a  a

In [91]: s.str.cat(f, join="left", na_rep="-")
Out[91]: 
0    aaa
1    bbb
2    c-c
3    ddd
dtype: string

将一个系列和多个对象连接成一个系列#

几个类似数组的项(具体地说: SeriesIndex ,和一维变体 np.ndarray )可以组合在一个类似列表的容器中(包括迭代器, dict -观点等)。

In [92]: s
Out[92]: 
0    a
1    b
2    c
3    d
dtype: string

In [93]: u
Out[93]: 
1    b
3    d
0    a
2    c
dtype: string

In [94]: s.str.cat([u, u.to_numpy()], join="left")
Out[94]: 
0    aab
1    bbd
2    cca
3    ddc
dtype: string

所有没有索引的元素(例如 np.ndarray ),在传递的列表中-like必须在长度上与调用匹配 Series (或 Index ),但是 SeriesIndex 可以具有任意长度(只要未禁用对齐 join=None ):

In [95]: v
Out[95]: 
-1    z
 0    a
 1    b
 3    d
 4    e
dtype: string

In [96]: s.str.cat([v, u, u.to_numpy()], join="outer", na_rep="-")
Out[96]: 
-1    -z--
 0    aaab
 1    bbbd
 2    c-ca
 3    dddc
 4    -e--
dtype: string

如果使用 join='right' 在一张类似于 others 包含不同的索引,则这些索引的并集将用作最终串联的基础:

In [97]: u.loc[[3]]
Out[97]: 
3    d
dtype: string

In [98]: v.loc[[-1, 0]]
Out[98]: 
-1    z
 0    a
dtype: string

In [99]: s.str.cat([u.loc[[3]], v.loc[[-1, 0]]], join="right", na_rep="-")
Out[99]: 
 3    dd-
-1    --z
 0    a-a
dtype: string

索引使用 .str#

您可以使用 [] 直接按位置位置编制索引的符号。如果索引超过字符串的结尾,则结果将是 NaN

In [100]: s = pd.Series(
   .....:     ["A", "B", "C", "Aaba", "Baca", np.nan, "CABA", "dog", "cat"], dtype="string"
   .....: )
   .....: 

In [101]: s.str[0]
Out[101]: 
0       A
1       B
2       C
3       A
4       B
5    <NA>
6       C
7       d
8       c
dtype: string

In [102]: s.str[1]
Out[102]: 
0    <NA>
1    <NA>
2    <NA>
3       a
4       a
5    <NA>
6       A
7       o
8       a
dtype: string

提取子字符串#

提取每个主题中的第一个匹配项(摘录)#

警告

版本0.23之前,参数 expandextract 方法默认为 False 。什么时候 expand=Falseexpand 返回一个 SeriesIndex ,或 DataFrame ,具体取决于主题和正则表达式模式。什么时候 expand=True ,则它始终返回一个 DataFrame 从用户的角度来看,这更一致,更不容易混淆。 expand=True 自0.23.0版以来一直是默认设置。

这个 extract method accepts a regular expression 至少有一个捕获组。

提取包含多个组的正则表达式将返回每个组包含一列的DataFrame。

In [103]: pd.Series(
   .....:     ["a1", "b2", "c3"],
   .....:     dtype="string",
   .....: ).str.extract(r"([ab])(\d)", expand=False)
   .....: 
Out[103]: 
      0     1
0     a     1
1     b     2
2  <NA>  <NA>

不匹配的元素返回一个填充了 NaN 。因此,一系列乱七八糟的字符串可以被“转换”成经过清理或更有用的字符串的类似索引的序列或DataFrame,而不需要 get() 要访问元组或 re.match 物体。结果的数据类型始终为Object,即使未找到匹配项并且结果仅包含 NaN

命名组,如

In [104]: pd.Series(["a1", "b2", "c3"], dtype="string").str.extract(
   .....:     r"(?P<letter>[ab])(?P<digit>\d)", expand=False
   .....: )
   .....: 
Out[104]: 
  letter digit
0      a     1
1      b     2
2   <NA>  <NA>

和可选的组,如

In [105]: pd.Series(
   .....:     ["a1", "b2", "3"],
   .....:     dtype="string",
   .....: ).str.extract(r"([ab])?(\d)", expand=False)
   .....: 
Out[105]: 
      0  1
0     a  1
1     b  2
2  <NA>  3

也可以使用。请注意,正则表达式中的任何捕获组名称都将用作列名;否则将使用捕获组编号。

使用一组提取正则表达式将返回一个 DataFrame 用一列if expand=True

In [106]: pd.Series(["a1", "b2", "c3"], dtype="string").str.extract(r"[ab](\d)", expand=True)
Out[106]: 
      0
0     1
1     2
2  <NA>

如果满足以下条件,它将返回一个系列 expand=False

In [107]: pd.Series(["a1", "b2", "c3"], dtype="string").str.extract(r"[ab](\d)", expand=False)
Out[107]: 
0       1
1       2
2    <NA>
dtype: string

访问一位 Index 如果正则表达式只有一个捕获组,则返回一个 DataFrame 用一列if expand=True

In [108]: s = pd.Series(["a1", "b2", "c3"], ["A11", "B22", "C33"], dtype="string")

In [109]: s
Out[109]: 
A11    a1
B22    b2
C33    c3
dtype: string

In [110]: s.index.str.extract("(?P<letter>[a-zA-Z])", expand=True)
Out[110]: 
  letter
0      A
1      B
2      C

它返回一个 Index 如果 expand=False

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

访问一位 Index 如果正则表达式具有多个捕获组,则返回 DataFrame 如果 expand=True

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

它提高了 ValueError 如果 expand=False

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

下表汇总了 extract(expand=False) (第一列输入主题,第一行regex中的组数)

1组

>1组

索引

索引

ValueError

系列

系列

DataFrame

提取每个主题中的所有匹配项(提取)#

不像 extract (它只返回第一个匹配项),

In [113]: s = pd.Series(["a1a2", "b1", "c1"], index=["A", "B", "C"], dtype="string")

In [114]: s
Out[114]: 
A    a1a2
B      b1
C      c1
dtype: string

In [115]: two_groups = "(?P<letter>[a-z])(?P<digit>[0-9])"

In [116]: s.str.extract(two_groups, expand=True)
Out[116]: 
  letter digit
A      a     1
B      b     1
C      c     1

这个 extractall 方法返回每个匹配项。结果是 extractall 永远是一种 DataFrame 使用一个 MultiIndex 在它的几排上。的最后一级 MultiIndex 被命名为 match 并指示主题中的顺序。

In [117]: s.str.extractall(two_groups)
Out[117]: 
        letter digit
  match             
A 0          a     1
  1          a     2
B 0          b     1
C 0          c     1

当系列中的每个主题字符串都恰好有一个匹配时,

In [118]: s = pd.Series(["a3", "b3", "c2"], dtype="string")

In [119]: s
Out[119]: 
0    a3
1    b3
2    c2
dtype: string

然后 extractall(pat).xs(0, level='match') 给出的结果与 extract(pat)

In [120]: extract_result = s.str.extract(two_groups, expand=True)

In [121]: extract_result
Out[121]: 
  letter digit
0      a     3
1      b     3
2      c     2

In [122]: extractall_result = s.str.extractall(two_groups)

In [123]: extractall_result
Out[123]: 
        letter digit
  match             
0 0          a     3
1 0          b     3
2 0          c     2

In [124]: extractall_result.xs(0, level="match")
Out[124]: 
  letter digit
0      a     3
1      b     3
2      c     2

Index 还支持 .str.extractall 。它返回一个 DataFrame ,它的结果与 Series.str.extractall 具有默认索引(从0开始)。

In [125]: pd.Index(["a1a2", "b1", "c1"]).str.extractall(two_groups)
Out[125]: 
        letter digit
  match             
0 0          a     1
  1          a     2
1 0          b     1
2 0          c     1

In [126]: pd.Series(["a1a2", "b1", "c1"], dtype="string").str.extractall(two_groups)
Out[126]: 
        letter digit
  match             
0 0          a     1
  1          a     2
1 0          b     1
2 0          c     1

测试匹配或包含模式的字符串#

您可以检查元素是否包含图案:

In [127]: pattern = r"[0-9][a-z]"

In [128]: pd.Series(
   .....:     ["1", "2", "3a", "3b", "03c", "4dx"],
   .....:     dtype="string",
   .....: ).str.contains(pattern)
   .....: 
Out[128]: 
0    False
1    False
2     True
3     True
4     True
5     True
dtype: boolean

或者元素是否与模式匹配:

In [129]: pd.Series(
   .....:     ["1", "2", "3a", "3b", "03c", "4dx"],
   .....:     dtype="string",
   .....: ).str.match(pattern)
   .....: 
Out[129]: 
0    False
1    False
2     True
3     True
4    False
5     True
dtype: boolean

1.1.0 新版功能.

In [130]: pd.Series(
   .....:     ["1", "2", "3a", "3b", "03c", "4dx"],
   .....:     dtype="string",
   .....: ).str.fullmatch(pattern)
   .....: 
Out[130]: 
0    False
1    False
2     True
3     True
4    False
5    False
dtype: boolean

备注

两者之间的区别 matchfullmatch ,以及 contains 就是严格: fullmatch 测试整个字符串是否与正则表达式匹配; match 测试从字符串的第一个字符开始的正则表达式是否匹配;以及 contains 测试字符串中任意位置的正则表达式是否匹配。

中的相应函数 re 这三种匹配模式的包是 re.fullmatchre.match ,以及 re.search ,分别为。

像这样的方法 matchfullmatchcontainsstartswith ,以及 endswith 多拿一张 na 参数,因此缺少的值可以被视为True或False:

In [131]: s4 = pd.Series(
   .....:     ["A", "B", "C", "Aaba", "Baca", np.nan, "CABA", "dog", "cat"], dtype="string"
   .....: )
   .....: 

In [132]: s4.str.contains("A", na=False)
Out[132]: 
0     True
1    False
2    False
3     True
4    False
5    False
6     True
7    False
8    False
dtype: boolean

创建指标变量#

您可以从字符串列中提取伪变量。例如,如果它们之间用 '|'

In [133]: s = pd.Series(["a", "a|b", np.nan, "a|c"], dtype="string")

In [134]: s.str.get_dummies(sep="|")
Out[134]: 
   a  b  c
0  1  0  0
1  1  1  0
2  0  0  0
3  1  0  1

细绳 Index 还支持 get_dummies 它返回一个 MultiIndex

In [135]: idx = pd.Index(["a", "a|b", np.nan, "a|c"])

In [136]: idx.str.get_dummies(sep="|")
Out[136]: 
MultiIndex([(1, 0, 0),
            (1, 1, 0),
            (0, 0, 0),
            (1, 0, 1)],
           names=['a', 'b', 'c'])

另请参阅 get_dummies()

方法摘要#

方法

描述

cat()

连接字符串

split()

在分隔符上拆分字符串

rsplit()

在从字符串末尾开始的分隔符上拆分字符串

get()

索引到每个元素(检索第i个元素)

join()

用传递的分隔符联接序列中每个元素中的字符串

get_dummies()

在返回伪变量的DataFrame的分隔符上拆分字符串

contains()

如果每个字符串包含模式/正则表达式,则返回布尔数组

replace()

将模式/正则表达式/字符串的匹配项替换为某个其他字符串或给定匹配项的可调用对象的返回值

removeprefix()

从字符串中删除前缀,即仅当字符串以前缀开头时才删除。

removesuffix()

从字符串中删除后缀,即仅当字符串以后缀结尾时才删除。

repeat()

重复值 (s.str.repeat(3) 相当于 x * 3 )

pad()

在字符串的左侧、右侧或两侧添加空格

center()

相当于 str.center

ljust()

相当于 str.ljust

rjust()

相当于 str.rjust

zfill()

相当于 str.zfill

wrap()

将长字符串拆分成长度小于给定宽度的行

slice()

切分系列中的每一根线

slice_replace()

将每个字符串中的切片替换为传递的值

count()

计算阵列的引用次数

startswith()

相当于 str.startswith(pat) 对于每个元素

endswith()

相当于 str.endswith(pat) 对于每个元素

findall()

计算每个字符串的模式/正则表达式的所有匹配项的列表

match()

打电话 re.match 在每个元素上,将匹配组作为列表返回

extract()

打电话 re.search 在每个元素上,返回DataFrame,每个元素占一行,每个正则表达式捕获组占一列

extractall()

打电话 re.findall 在每个元素上,返回DataFrame,每个匹配项占一行,每个正则表达式捕获组占一列

len()

计算字符串长度

strip()

相当于 str.strip

rstrip()

相当于 str.rstrip

lstrip()

相当于 str.lstrip

partition()

相当于 str.partition

rpartition()

相当于 str.rpartition

lower()

相当于 str.lower

casefold()

相当于 str.casefold

upper()

相当于 str.upper

find()

相当于 str.find

rfind()

相当于 str.rfind

index()

相当于 str.index

rindex()

相当于 str.rindex

capitalize()

相当于 str.capitalize

swapcase()

相当于 str.swapcase

normalize()

返回Unicode范式。相当于 unicodedata.normalize

translate()

相当于 str.translate

isalnum()

相当于 str.isalnum

isalpha()

相当于 str.isalpha

isdigit()

相当于 str.isdigit

isspace()

相当于 str.isspace

islower()

相当于 str.islower

isupper()

相当于 str.isupper

istitle()

相当于 str.istitle

isnumeric()

相当于 str.isnumeric

isdecimal()

相当于 str.isdecimal