接下来,讲解如何采用正则的方式提取DataFrame子集
==
- str.contains():包含一个特定的字符串
- 参数na:缺少值NaN处理
- 参数case:大小写的处理
- 参数regex:使用正则表达式模式- str.endswith():以特定字符串结尾
- str.startswith():以特定的字符串开头
- str.match():匹配正则表达式模式
注:要提取部分匹配的行,可以使用pandas的(str.xxx())方法,根据指定条件提取的字符串方法。
import pandas as pd
df = pd.read_csv('sample.csv').head(3)
print(df)
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
12345678
使用布尔列表(数组)或pandas.Series,只能提取(选择)True行。
mask = [True, False, True]
df_mask = df[mask]
print(df_mask)
# name age state point
# 0 Alice 24 NY 64
# 2 Charlie 18 CA 70
123456
因此,对于具有字符串元素的列,是否能够获得根据条件的布尔列表就足够了。
==
)如果元素与字符串完全匹配,则使用==
获取为True
的pandas.Series
。
print(df['state'] == 'CA')
# 0 False
# 1 True
# 2 True
# Name: state, dtype: bool
print(df[df['state'] == 'CA'])
# name age state point
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
pandas.Series
或pandas.index(columns)
字符串方法str.contains()
允许获取包含特定字符串的pandas.Series
.
print(df['name'].str.contains('li'))
# 0 True
# 1 False
# 2 True
# Name: name, dtype: bool
print(df[df['name'].str.contains('li')])
# name age state point
# 0 Alice 24 NY 64
# 2 Charlie 18 CA 70
请注意,默认情况下,第一个参数中指定的字符串将作为正则表达式模式进行处理,如下所述。
如果元素是缺失值NaN,则默认情况下它将返回NaN而不是True或False。因此,使用pandas.Series提取该行是错误的。
df_nan = df.copy()
df_nan.iloc[2, 0] = float('nan')
print(df_nan)
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 92
# 2 NaN 18 CA 70
print(df_nan['name'].str.contains('li'))
# 0 True
# 1 False
# 2 NaN
# Name: name, dtype: object
# print(df_nan[df_nan['name'].str.contains('li')])
# ValueError: cannot index with vector containing NA / NaN values
可以通过str.contains()
的参数na
来指定替换NaN结果的值。
print(df_nan['name'].str.contains('li', na=False))
# 0 True
# 1 False
# 2 False
# Name: name, dtype: bool
print(df_nan['name'].str.contains('li', na=True))
# 0 True
# 1 False
# 2 True
# Name: name, dtype: bool
用作条件时,如果na = True,则选择NaN的行,如果na = False,则不选择NaN的行。
默认情况下,区分大小写。如果参数case为False,则case被忽略。
print(df['name'].str.contains('LI'))
# 0 False
# 1 False
# 2 False
# Name: name, dtype: bool
print(df['name'].str.contains('LI', case=False))
# 0 True
# 1 False
# 2 True
# Name: name, dtype: bool
使用str.contains()
时要记住的一件事是,默认情况下,指定为第一个参数的字符串将作为正则表达式模式进行处理。
print(df['name'].str.contains('i.*e'))
# 0 True
# 1 False
# 2 True
# Name: name, dtype: bool
如果参数ragex为False,则确定是否包含第一个参数的字符串本身。
print(df['name'].str.contains('i.*e', regex=False))
# 0 False
# 1 False
# 2 False
# Name: name, dtype: bool
例如,如果要判断是否包含正则表达式的特殊字符,例如? . *
,则需要设置regex = False。当然,可以指定一个正则表达式模式,以转义\?
等特殊字符。
请注意,默认值可能会导致错误。
df_q = df.copy()
df_q.iloc[2, 0] += '?'
print(df_q)
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 92
# 2 Charlie? 18 CA 70
# print(df_q['name'].str.contains('?'))
# error: nothing to repeat at position 0
print(df_q['name'].str.contains('?', regex=False))
# 0 False
# 1 False
# 2 True
# Name: name, dtype: bool
print(df_q['name'].str.contains('\?'))
# 0 False
# 1 False
# 2 True
# Name: name, dtype: bool
str.contains()
等同于re.search()
,并且可以在flags参数中指定正则表达式标志。如稍后所述,还有对应于re.match()
的str.match()
。
pandas.Series
字符串方法str.endswith()
可以获取以特定字符串结尾的pandas.Series
。
print(df['name'].str.endswith('e'))
# 0 True
# 1 False
# 2 True
# Name: name, dtype: bool
print(df[df['name'].str.endswith('e')])
# name age state point
# 0 Alice 24 NY 64
# 2 Charlie 18 CA 70
str.endswith()
也有一个参数na
。如果要选择缺失值NaN的行,则设置na = True;如果不想选择,则将na = False设置。
没有参数case,因此它始终区分大小写。
另外,第一个参数的字符串不作为正则表达式模式处理。
pandas.Series
字符串方法str.startswith()
可以获取以特定字符串开头的pandas.Series
。
print(df['name'].str.startswith('B'))
# 0 False
# 1 True
# 2 False
# Name: name, dtype: bool
print(df[df['name'].str.startswith('B')])
# name age state point
# 1 Bob 42 CA 92
pandas.Series
字符串方法str.match()
可以获取与正则表达式模式匹配的pandas.Series
。
print(df['name'].str.match('.*i.*e'))
# 0 True
# 1 False
# 2 True
# Name: name, dtype: bool
print(df[df['name'].str.match('.*i.*e')])
# name age state point
# 0 Alice 24 NY 64
# 2 Charlie 18 CA 70
如上所述,
str.match()
对应于re.match()
,并确定字符串的开头是否与模式匹配。如果不是一开始就为False。
print(df['name'].str.match('.*i'))
# 0 True
# 1 False
# 2 True
# Name: name, dtype: bool
print(df['name'].str.match('i.*e'))
# 0 False
# 1 False
# 2 False
# Name: name, dtype: bool
1234567891011
当需要确定是否包括与模式匹配的部分时,不仅在开始时,而且默认使用与上述
re.search()
等效的re.contains()
(regex = True)。
str.match()
与str.contains()
可以以相同的方式指定参数na
,case
和flag
。