首页 > 其他分享 >Pandas 2.2 中文官方教程和指南(十五)

Pandas 2.2 中文官方教程和指南(十五)

时间:2024-04-24 12:14:34浏览次数:24  
标签:教程 pd string dtype str Series 2.2 Pandas Out

原文:pandas.pydata.org/docs/

处理文本数据

原文:pandas.pydata.org/docs/user_guide/text.html

文本数据类型

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

  1. object -dtype NumPy 数组。

  2. StringDtype 扩展类型。

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

在 pandas 1.0 之前,object dtype 是唯一的选项。这在很多方面都是不幸的:

  1. 你可能会在object dtype 数组中意外存储字符串和非字符串的混合。最好有一个专用的 dtype。

  2. object dtype 会破坏 dtype 特定的操作,比如DataFrame.select_dtypes()。没有明确的方法可以仅选择文本而排除非文本但仍为 object-dtype 的列。

  3. 在阅读代码时,object dtype 数组的内容比'string'不够清晰。

目前,字符串和arrays.StringArrayobject dtype 数组的性能大致相同。我们期待未来的增强将显著提高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 

或在创建SeriesDataFrame之后进行astype

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 

你也可以在非字符串数据上使用StringDtype/"string"作为 dtype,并将其转换为string dtype:

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 dtype 不同的地方

  1. 对于 StringDtype,返回数字输出的 string 访问器方法将始终返回可空整数 dtype,而不是根据 NA 值的存在返回 int 或 float dtype。返回布尔值输出的方法将返回可空布尔 dtype。

    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 dtype。与 object-dtype 进行比较

    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 值时,输出 dtype 为 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 
    
  2. 一些字符串方法,比如Series.str.decode()StringArray上不可用,因为StringArray只保存字符串,而不是字节。

  3. 在比较操作中,arrays.StringArray和由StringArray支持的Series将返回一个具有BooleanDtype的对象,而不是bool dtype 对象。在StringArray中的缺失值将在比较操作中传播,而不总是像numpy.nan那样比较不相等。

本文档其余部分中的所有内容同样适用于stringobject dtype。 ## 字符串方法

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>可能更快。性能差异来自于category类型的Series上的字符串操作是在.categories上执行的,而不是在Series的每个元素上执行。

请注意,具有字符串.categoriescategory类型Series与字符串类型的Series相比存在一些限制(例如,如果scategory类型的Series,则无法将字符串相加:s + " " + s不起作用)。此外,对于这样的Series,不可用于操作list类型元素的.str方法。

警告

Series 的类型是推断的,并且允许的类型(即字符串)。

一般来说,.str访问器仅用于字符串。除了极少数例外情况外,不支持其他用途,并且可能在以后被禁用。 ## 拆分和替换字符串

split这样的方法返回一个列表的 Series:

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 

可以轻松扩展此操作以使用expand返回 DataFrame。

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 

当原始Series具有StringDtype时,输出列也将全部是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方法可以选择使用正则表达式

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 

在 2.0 版本中更改。

使用regex=True的单个字符模式也将被视为正则表达式:

In [48]: s4 = pd.Series(["a.b", ".", "b", np.nan, ""], dtype="string")

In [49]: s4
Out[49]: 
0     a.b
1       .
2       b
3    <NA>
4 
dtype: string

In [50]: s4.str.replace(".", "a", regex=True)
Out[50]: 
0     aaa
1       a
2       a
3    <NA>
4 
dtype: string 

如果您想要对字符串进行字面替换(相当于str.replace()),您可以将可选的regex参数设置为False,而不是转义每个字符。在这种情况下,patrepl都必须是字符串:

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

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

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

replace方法还可以接受一个可调用对象作为替换。它会对每个pat使用re.sub()进行调用。可调用对象应该期望一个位置参数(一个正则表达式对象)并返回一个字符串。

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

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

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

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

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

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

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

In [60]: import re

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

In [62]: s3.str.replace(regex_pat, "XX-XX ", regex=True)
Out[62]: 
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 

在调用带有编译的正则表达式对象的replace时包含一个flags参数将引发ValueError

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

removeprefixremovesuffix与 Python 3.9 中添加的str.removeprefixstr.removesuffix具有相同的效果 <docs.python.org/3/library/stdtypes.html#str.removeprefix>`__:

在 1.4.0 版本中新增。

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

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

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

In [67]: s.str.removesuffix("_str")
Out[67]: 
0          foo
1          bar
2    no_suffix
dtype: object 
```  ## 连接

有几种方法可以连接`Series`或`Index`,可以是与自身或其他对象连接,都基于`cat()`,或者`Index.str.cat`。

### 将单个 Series 连接成字符串

`Series`(或`Index`)的内容可以进行连接:

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

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

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

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

默认情况下,会忽略缺失值。使用na_rep,可以为缺失值指定一个表示:

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

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

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

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

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

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

任一侧存在缺失值都会导致结果中也存在缺失值,除非指定了na_rep

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

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

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

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

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

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

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

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

将一个 Series 和一个带索引的对象连接成一个 Series,并进行对齐

对于与SeriesDataFrame连接,可以通过设置join关键字来在连接之前对齐索引。

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

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

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

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

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

对于join,可以使用常规选项之一('left', 'outer', 'inner', 'right')。特别是,对齐也意味着不同长度不再需要一致。

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

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

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

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

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

others是一个DataFrame时,可以使用相同的对齐:

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

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

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

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

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

几个类似数组的项目(特别是:SeriesIndexnp.ndarray的一维变体)可以组合在一个类似列表的容器中(包括迭代器、dict-视图等)。

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

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

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

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

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

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

如果在一个包含不同索引的others列表上使用join='right',这些索引的并集将被用作最终连接的基础:

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

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

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

使用.str进行索引

您可以使用[]表示法直接按位置索引。如果索引超出字符串的末尾,结果将是一个NaN

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

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

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

提取子字符串

提取每个主题中的第一个匹配项(extract)

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

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

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

不匹配的元素返回一个填充有NaN的行。因此,一系列混乱的字符串可以被“转换”为一个具有相同索引的清理或更有用的字符串的系列或DataFrame,而不需要使用get()来访问元组或re.match对象。结果的数据类型始终为对象,即使没有找到匹配项,结果仅包含NaN

命名组如

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

和可选组如

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

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

使用一个组的正则表达式提取返回一个列的DataFrame,如果expand=True

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

如果expand=False,则返回一个 Series。

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

使用正则表达式调用带有一个捕获组的Index,如果expand=True,则返回一个列的DataFrame

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

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

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

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

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

使用具有多个捕获组的正则表达式调用Index,如果expand=True,则返回一个DataFrame

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

如果expand=False,则引发ValueError

In [116]: s.index.str.extract("(?P<letter>[a-zA-Z])([0-9]+)", expand=False)
---------------------------------------------------------------------------
ValueError  Traceback (most recent call last)
Cell In[116], line 1
----> 1 s.index.str.extract("(?P<letter>[a-zA-Z])([0-9]+)", expand=False)

File ~/work/pandas/pandas/pandas/core/strings/accessor.py:137, in forbid_nonstring_types.<locals>._forbid_nonstring_types.<locals>.wrapper(self, *args, **kwargs)
  132     msg = (
  133         f"Cannot use .str.{func_name} with values of "
  134         f"inferred dtype '{self._inferred_dtype}'."
  135     )
  136     raise TypeError(msg)
--> 137 return func(self, *args, **kwargs)

File ~/work/pandas/pandas/pandas/core/strings/accessor.py:2743, in StringMethods.extract(self, pat, flags, expand)
  2740     raise ValueError("pattern contains no capture groups")
  2742 if not expand and regex.groups > 1 and isinstance(self._data, ABCIndex):
-> 2743     raise ValueError("only one regex group is supported with Index")
  2745 obj = self._data
  2746 result_dtype = _result_dtype(obj)

ValueError: only one regex group is supported with Index 

下表总结了extract(expand=False)的行为(第一列为输入主题,正则表达式中的组数为第一行)

1 组 >1 组
Index Index ValueError
Series Series DataFrame

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

与仅返回第一个匹配项的extract不同,

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

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

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

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

extractall方法返回每个匹配项。extractall的结果始终是一个带有MultiIndexDataFrameMultiIndex的最后一级命名为match,表示主题中的顺序。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

您可以检查元素是否包含模式:

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

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

或者元素是否匹配模式:

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

注意

matchfullmatchcontains之间的区别在于严格性:fullmatch测试整个字符串是否与正则表达式匹配;match测试正则表达式是否在字符串的第一个字符处匹配;contains测试字符串中是否在任何位置匹配正则表达式。

这三种匹配模式在re包中对应的函数分别是re.fullmatchre.matchre.search

matchfullmatchcontainsstartswithendswith等方法接受额外的na参数,因此缺失值可以被视为 True 或 False:

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

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

创建指示变量

您可以从字符串列中提取虚拟变量。例如,如果它们由'|'分隔:

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

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

字符串Index还支持get_dummies,它返回一个MultiIndex

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

In [140]: idx.str.get_dummies(sep="|")
Out[140]: 
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() 使用传递的分隔符连接 Series 中每个元素的字符串
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() 对 Series 中的每个字符串进行切片
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

文本数据类型

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

  1. object -dtype NumPy 数组。

  2. StringDtype 扩展类型。

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

在 pandas 1.0 之前,object dtype 是唯一的选择。这在很多方面都是不幸的:

  1. object dtype 数组中可能会意外存储字符串和非字符串的混合。最好使用专用的 dtype。

  2. object dtype 会破坏 dtype 特定的操作,比如DataFrame.select_dtypes()。没有明确的方法可以仅选择文本而排除非文本但仍为 object-dtype 的列。

  3. 阅读代码时,object dtype 数组的内容不如'string'清晰。

目前,object dtype 类型的字符串数组和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 

在创建SeriesDataFrame之后使用astype

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 

你也可以在非字符串数据上使用StringDtype/"string"作为 dtype,它将被转换为string dtype:

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 dtype 不同的地方

  1. 对于StringDtype,返回numeric输出的 string 访问器方法将始终返回可空整数 dtype,而不是根据 NA 值的存在而返回 int 或 float dtype。返回boolean输出的方法将返回可空布尔 dtype。

    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 dtype。与 object-dtype 进行比较

    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 值时,输出 dtype 为 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 
    
  2. 一些字符串方法,比如Series.str.decode()StringArray上不可用,因为StringArray只保存字符串,而不是字节。

  3. 在比较操作中,arrays.StringArray和由StringArray支持的Series将返回一个带有BooleanDtype的对象,而不是bool dtype 对象。在StringArray中的缺失值将在比较操作中传播,而不像numpy.nan那样总是比较不相等。

本文档其余部分中的其他内容同样适用于stringobject dtype。### 行为差异

这些是StringDtype对象的行为与object dtype 不同的地方

  1. 对于StringDtype,返回numeric输出的 string 访问器方法将始终返回可空整数 dtype,而不是根据 NA 值的存在而返回 int 或 float dtype。返回boolean输出的方法将返回可空布尔 dtype。

    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 dtype。与 object-dtype 进行比较

    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 值时,输出 dtype 为 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 
    
  2. 一些字符串方法,比如Series.str.decode()StringArray上不可用,因为StringArray只保存字符串,而不是字节。

  3. 在比较操作中,由StringArray支持的arrays.StringArraySeries将返回一个具有BooleanDtype的对象,而不是bool dtype 对象。在StringArray中的缺失值将在比较操作中传播,而不像numpy.nan那样总是比较不相等。

本文档其余部分中的所有内容同样适用于stringobject dtype。

字符串方法

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') 

索引上的字符串方法特别适用于清理或转换 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>可能会更快。性能差异在于,对于category类型的Series,字符串操作是在.categories上而不是在Series的每个元素上进行的。

请注意,具有字符串.categoriescategory类型的Series与字符串类型的Series相比存在一些限制(例如,如果scategory类型的Series,则无法将字符串添加到彼此:s + " " + s不起作用)。此外,对list类型元素进行操作的.str方法在此类Series上不可用。

警告

系列的类型是推断的,允许的类型为(即字符串)。

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

拆分和替换字符串

split这样的方法会返回一个列表的 Series:

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 

使用expand很容易扩展到返回 DataFrame。

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 

当原始Series具有StringDtype时,输出列也将全部是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可选使用正则表达式

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 

版本 2.0���的更改。

使用regex=True的单个字符模式也将被视为正则表达式:

In [48]: s4 = pd.Series(["a.b", ".", "b", np.nan, ""], dtype="string")

In [49]: s4
Out[49]: 
0     a.b
1       .
2       b
3    <NA>
4 
dtype: string

In [50]: s4.str.replace(".", "a", regex=True)
Out[50]: 
0     aaa
1       a
2       a
3    <NA>
4 
dtype: string 

如果要对字符串进行字面替换(相当于str.replace()),可以将可选的regex参数设置为False,而不是转义每个字符。在这种情况下,patrepl都必须是字符串:

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

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

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

replace方法还可以将可调用对象作为替换。它会使用re.sub()对每个pat进行调用。可调用对象应该期望一个位置参数(一个正则表达式对象)并返回一个字符串。

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

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

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

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

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

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

replace方法还接受从re.compile()编译的正则表达式对象作为模式。所有标志应包含在编译的正则表达式对象中。

In [60]: import re

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

In [62]: s3.str.replace(regex_pat, "XX-XX ", regex=True)
Out[62]: 
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 

在使用编译的正则表达式对象调用replace时包含flags参数将引发ValueError

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

removeprefixremovesuffix与 Python 3.9 中添加的str.removeprefixstr.removesuffix具有相同的效果 <docs.python.org/3/library/stdtypes.html#str.removeprefix>`__:

版本 1.4.0 中的新功能。

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

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

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

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

连接

有几种方法可以连接SeriesIndex,无论是与自身还是其他对象,都基于cat()Index.str.cat

将单个 Series 连接成字符串

可以连接Series(或Index)的内容:

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

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

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

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

默认情况下,缺失值会被忽略。使用na_rep,它们可以被赋予一个表示:

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

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

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

将 Series 和类似列表的内容连接成 Series

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

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

任一侧的缺失值也会导致结果中的缺失值,除非指定了na_rep

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

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

将 Series 和类似数组的内容连接成 Series

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

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

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

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

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

将 Series 和索引对象连接成 Series,进行对齐

对于与SeriesDataFrame连接,可以通过设置join关键字来在连接之前对齐索引。

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

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

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

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

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

对于join的常见选项(其中之一为'left', 'outer', 'inner', 'right')都是可用的。特别是,对齐也意味着不同长度不再需要一致。

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

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

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

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

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

others是一个DataFrame时,可以使用相同的对齐方式:

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

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

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

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

将一个 Series 和多个对象连接成一个 Series

几个类似数组的项目(具体来说:SeriesIndexnp.ndarray的一维变体)可以组合在一个类似列表的容器中(包括迭代器,dict视图等)。

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

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

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

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

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

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

如果在包含不同索引的others列表上使用join='right',则这些索引的并集将被用作最终连接的基础:

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

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

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

将一个单独的 Series 连接成一个字符串

可以连接Series(或Index)的内容:

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

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

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

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

默认情况下,缺失值会被忽略。使用na_rep,它们可以被赋予一个表示:

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

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

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

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

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

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

任一侧的缺失值也会导致结果中的缺失值,除非指定了na_rep

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

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

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

参数others也可以是二维的。在这种情况下,行数必须与调用的Series(或Index)的长度相匹配。

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

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

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

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

将一个 Series 和一个带索引的对象连接成一个 Series,带有对齐

对于与SeriesDataFrame连接,可以通过设置join关键字来在连接之前对齐索引。

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

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

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

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

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

对于join的常见选项(其中之一为'left', 'outer', 'inner', 'right')都是可用的。特别是,对齐也意味着不同长度不再需要一致。

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

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

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

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

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

others是一个DataFrame时,可以使用相同的对齐方式:

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

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

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

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

将一个 Series 和多个对象连接成一个 Series

几个类似数组的项目(具体来说:SeriesIndexnp.ndarray的一维变体)可以组合在一个类似列表的容器中(包括迭代器,dict视图等)。

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

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

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

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

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

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

如果在包含不同索引的others列表上使用join='right',则这些索引的并集将被用作最终连接的基础:

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

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

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

使用.str进行索引

您可以使用 [] 符号直接按位置索引。如果索引超出字符串的末尾,结果将是一个 NaN

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

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

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

提取子字符串

提取每个主题中的第一个匹配项(extract)

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

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

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

不匹配的元素返回一个填充有 NaN 的行。因此,一系列混乱的字符串可以“转换”为一个具有相同索引的已清理或更有用的字符串的 Series 或 DataFrame,而无需使用 get() 访问元组或 re.match 对象。结果的 dtype 始终为 object,即使未找到匹配项,结果仅包含 NaN

命名组如

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

和可选组

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

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

提取具有一个组的正则表达式将返回一个列的 DataFrame,如果 expand=True

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

如果 expand=False,则返回一个 Series。

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

对具有正好一个捕获组的正则表达式的 Index 调用,如果 expand=True,则返回一个列。

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

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

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

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

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

对具有多个捕获组的正则表达式的 Index 调用,如果 expand=True,则返回一个 DataFrame。

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

如果 expand=False,则引发 ValueError

In [116]: s.index.str.extract("(?P<letter>[a-zA-Z])([0-9]+)", expand=False)
---------------------------------------------------------------------------
ValueError  Traceback (most recent call last)
Cell In[116], line 1
----> 1 s.index.str.extract("(?P<letter>[a-zA-Z])([0-9]+)", expand=False)

File ~/work/pandas/pandas/pandas/core/strings/accessor.py:137, in forbid_nonstring_types.<locals>._forbid_nonstring_types.<locals>.wrapper(self, *args, **kwargs)
  132     msg = (
  133         f"Cannot use .str.{func_name} with values of "
  134         f"inferred dtype '{self._inferred_dtype}'."
  135     )
  136     raise TypeError(msg)
--> 137 return func(self, *args, **kwargs)

File ~/work/pandas/pandas/pandas/core/strings/accessor.py:2743, in StringMethods.extract(self, pat, flags, expand)
  2740     raise ValueError("pattern contains no capture groups")
  2742 if not expand and regex.groups > 1 and isinstance(self._data, ABCIndex):
-> 2743     raise ValueError("only one regex group is supported with Index")
  2745 obj = self._data
  2746 result_dtype = _result_dtype(obj)

ValueError: only one regex group is supported with Index 

下表总结了 extract(expand=False) 的行为(输入主题在第一列,正则表达式中的组数在第一行)

1 组 >1 组
Index Index ValueError
Series Series DataFrame

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

与仅返回第一个匹配项的 extract 不同,

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

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

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

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

extractall 方法返回每个匹配项。extractall 的结果始终是一个具有行上的 MultiIndex 的 DataFrame。MultiIndex 的最后一级命名为 match,表示主题中的顺序。

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

当 Series 中的每个主题字符串恰好有一个匹配项时,

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

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

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

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

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

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

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

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

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

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

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

提取每个主题中的第一个匹配项(extract)

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

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

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

不匹配的元素返回一个填充有 NaN 的行。因此,一系列混乱的字符串可以“转换”为一个具有相同索引的已清理或更有用的字符串的 Series 或 DataFrame,而无需使用 get() 访问元组或 re.match 对象。结果的 dtype 始终为 object,即使未找到匹配项,结果仅包含 NaN

命名组如

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

和可选���

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

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

使用一个组提取正则表达式,如果expand=True,则返回一个列的DataFrame

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

如果expand=False,则返回一个 Series。

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

对具有正好一个捕获组的正则表达式调用Index,如果expand=True,则返回一个列的DataFrame

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

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

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

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

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

对具有多个捕获组的正则表达式调用Index,如果expand=True,则返回一个DataFrame

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

如果expand=False,则会引发ValueError

In [116]: s.index.str.extract("(?P<letter>[a-zA-Z])([0-9]+)", expand=False)
---------------------------------------------------------------------------
ValueError  Traceback (most recent call last)
Cell In[116], line 1
----> 1 s.index.str.extract("(?P<letter>[a-zA-Z])([0-9]+)", expand=False)

File ~/work/pandas/pandas/pandas/core/strings/accessor.py:137, in forbid_nonstring_types.<locals>._forbid_nonstring_types.<locals>.wrapper(self, *args, **kwargs)
  132     msg = (
  133         f"Cannot use .str.{func_name} with values of "
  134         f"inferred dtype '{self._inferred_dtype}'."
  135     )
  136     raise TypeError(msg)
--> 137 return func(self, *args, **kwargs)

File ~/work/pandas/pandas/pandas/core/strings/accessor.py:2743, in StringMethods.extract(self, pat, flags, expand)
  2740     raise ValueError("pattern contains no capture groups")
  2742 if not expand and regex.groups > 1 and isinstance(self._data, ABCIndex):
-> 2743     raise ValueError("only one regex group is supported with Index")
  2745 obj = self._data
  2746 result_dtype = _result_dtype(obj)

ValueError: only one regex group is supported with Index 

下表总结了extract(expand=False)的行为(第一列为输入主题,第一行为正则表达式中的组数)

1 组 >1 组
Index Index ValueError
Series Series DataFrame

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

与仅返回第一个匹配的extract不同,

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

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

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

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

extractall方法返回每个匹配。extractall的结果始终是具有其行上的MultiIndexDataFrameMultiIndex的最后一级命名为match,表示主题中的顺序。

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

当 Series 中的每个主题字符串正好有一个匹配时,

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

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

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

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

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

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

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

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

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

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

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

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

您可以检查元素是否包含模式:

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

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

或者元素是否匹配模式:

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

注意

matchfullmatchcontains之间的区别是严格性:fullmatch测试整个字符串是否与正则表达式匹配;match测试字符串的第一个字符是否有正则表达式的匹配;contains测试字符串中是否有正则表达式的匹配。

这三种匹配模式的re包中对应的函数分别是re.fullmatchre.matchre.search

matchfullmatchcontainsstartswithendswith等方法接受额外的na参数,以便将缺失值视为 True 或 False:

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

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

创建指示变量

您可以从字符串列中提取虚拟变量。例如,如果它们由'|'分隔:

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

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

字符串Index也支持get_dummies,它返回一个MultiIndex

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

In [140]: idx.str.get_dummies(sep="|")
Out[140]: 
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() 使用传递的分隔符将 Series 中每个元素的字符串连接起来
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() 切片 Series 中的每个字符串
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

标签:教程,pd,string,dtype,str,Series,2.2,Pandas,Out
From: https://www.cnblogs.com/apachecn/p/18154770

相关文章

  • Pandas 2.2 中文官方教程和指南(十四)
    原文:pandas.pydata.org/docs/重塑和透视表原文:pandas.pydata.org/docs/user_guide/reshaping.htmlpandas提供了用于操作Series和DataFrame的方法,以改变数据的表示形式,以便进行进一步的数据处理或数据汇总。pivot()和pivot_table():在一个或多个离散类别中对唯一值进行......
  • Pandas 2.2 中文官方教程和指南(五)
    原文:pandas.pydata.org/docs/与SAS的比较译文:pandas.pydata.org/docs/getting_started/comparison/comparison_with_sas.html对于来自SAS的潜在用户,本页面旨在演示如何在pandas中执行不同的SAS操作。如果您是pandas的新手,您可能首先想通过阅读10分钟入门pandas......
  • Pandas 2.2 中文官方教程和指南(四)
    原文:pandas.pydata.org/docs/与SQL比较原文:pandas.pydata.org/docs/getting_started/comparison/comparison_with_sql.html由于许多潜在的pandas用户对SQL有一定的了解,本页旨在提供使用pandas执行各种SQL操作的一些示例。如果你是pandas的新手,你可能想先阅读......
  • Pandas 2.2 中文官方教程和指南(一)
    原文:pandas.pydata.org/docs/安装原文:pandas.pydata.org/docs/getting_started/install.html安装pandas的最简单方法是作为Anaconda发行版的一部分安装,这是一个用于数据分析和科学计算的跨平台发行版。Conda包管理器是大多数用户推荐的安装方法。还提供了从源代码安装(#i......
  • Pandas 2.2 中文官方教程和指南(十二)
    原文:pandas.pydata.org/docs/MultiIndex/高级索引原文:pandas.pydata.org/docs/user_guide/advanced.html本节涵盖了使用MultiIndex进行索引和其他高级索引功能。查看数据索引和选择以获取一般索引文档。警告在设置操作中返回副本还是引用可能取决于上下文。有时这被......
  • Pandas 2.2 中文官方教程和指南(十六)
    原文:pandas.pydata.org/docs/处理缺失数据原文:pandas.pydata.org/docs/user_guide/missing_data.html被视为“缺失”的值pandas使用不同的标记值来表示缺失值(也称为NA),具体取决于数据类型。numpy.nan适用于NumPy数据类型。使用NumPy数据类型的缺点是原始数据类型将......
  • Pandas 2.2 中文官方教程和指南(十三)
    原文:pandas.pydata.org/docs/写时复制(CoW)原文:pandas.pydata.org/docs/user_guide/copy_on_write.html注意写时复制将成为pandas3.0的默认设置。我们建议现在就启用它以从所有改进中受益。写时复制首次引入于版本1.5.0。从版本2.0开始,大部分通过CoW可能实现和支持......
  • Pandas 2.2 中文官方教程和指南(十七)
    原文:pandas.pydata.org/docs/重复标签原文:pandas.pydata.org/docs/user_guide/duplicates.htmlIndex对象不需要是唯一的;你可以有重复的行或列标签。这一点可能一开始会有点困惑。如果你熟悉SQL,你会知道行标签类似于表上的主键,你绝不希望在SQL表中有重复项。但pandas的......
  • Pandas 2.2 中文官方教程和指南(六)
    原文:pandas.pydata.org/docs/与Stata的比较原文:pandas.pydata.org/docs/getting_started/comparison/comparison_with_stata.html对于可能来自Stata的潜在用户,本页面旨在演示如何在pandas中执行不同的Stata操作。如果您是pandas的新手,您可能首先想通过阅读10分......
  • Pandas 2.2 中文官方教程和指南(七)
    原文:pandas.pydata.org/docs/社区教程原文:pandas.pydata.org/docs/getting_started/tutorials.html这是社区提供的许多pandas教程的指南,主要面向新用户。由JuliaEvans撰写的pandascookbook这本2015年的cookbook(由JuliaEvans撰写)的目标是为您提供一些具体的示......