行业资讯
Pandas字符串匹配实战:从完全匹配到正则表达式高效筛选数据行
1. 从“找东西”说起为什么字符串匹配是数据处理的基本功做数据分析尤其是用Pandas处理表格数据有一个场景几乎每天都会遇到在一大堆数据里找到包含特定“关键词”的那些行。这个“关键词”可能是一个客户的名字、一个产品的型号代码、一段日志里的错误信息或者一个订单状态。听起来很简单不就是“找东西”吗但就是这个看似简单的操作在实际工作中却藏着不少门道。比如你想找所有包含“ERROR”的日志行是只要行里出现了“ERROR”这几个字母就算还是必须整段文本完全等于“ERROR”又或者你想找名字里带“张”的所有客户这个“张”字可能出现在姓里也可能出现在名里你怎么高效地把它筛出来这就是标题里说的“完全匹配”和“部分匹配”的区别。很多新手甚至一些有经验的数据工程师在处理这类需求时往往会写出一堆冗长、低效甚至容易出错的代码。我自己在早期项目里就没少踩坑曾经为了在一个几百万行的日志文件里筛选特定错误类型写了个蹩脚的循环跑起来慢得像蜗牛还差点把服务器内存撑爆。后来才明白Pandas早就为这些场景准备好了“瑞士军刀”用对了方法一行代码就能优雅又高效地解决问题。今天我就结合自己十多年的数据处理经验把Pandas里提取含有指定字符串行的各种姿势从最基础的完全匹配到灵活的部分匹配再到一些高级的正则表达式技巧掰开揉碎了讲清楚。我会重点解释每种方法背后的逻辑、适用场景以及那些官方文档里不会写的“坑”和实战技巧。无论你是刚接触Pandas还是想优化手头的代码相信这篇都能给你带来实实在在的帮助。2. 完全匹配当“一字不差”成为铁律完全匹配顾名思义就是要求目标列中的字符串必须和我们指定的搜索词一模一样不多一个字符不少一个字符连大小写和空格都必须一致。这听起来很严格但在很多业务场景下却是必须的。比如你有一张用户状态表状态字段的值可能是精确的ACTIVE,INACTIVE,PENDING。当你需要筛选出所有PENDING状态的用户时你肯定不希望把PENDING REVIEW或者pending小写也混进来。2.1 核心武器操作符与.isin()方法在Pandas中实现完全匹配最直接、最高效的工具就是布尔索引配合操作符。假设我们有一个简单的DataFramedf记录了一些订单信息import pandas as pd data { 订单号: [A001, A002, A003, A004, A005], 客户姓名: [张三, 李四, 王五, 赵六, 孙七], 订单状态: [已支付, 待发货, 已支付, 已取消, 待发货], 产品代码: [PROD-100, PROD-101, PROD-100, PROD-102, PROD-101] } df pd.DataFrame(data) print(df)输出订单号 客户姓名 订单状态 产品代码 0 A001 张三 已支付 PROD-100 1 A002 李四 待发货 PROD-101 2 A003 王五 已支付 PROD-100 3 A004 赵六 已取消 PROD-102 4 A005 孙七 待发货 PROD-101现在我们想筛选出所有订单状态为“已支付”的行。# 使用 操作符进行完全匹配 paid_orders df[df[订单状态] 已支付] print(paid_orders)输出订单号 客户姓名 订单状态 产品代码 0 A001 张三 已支付 PROD-100 2 A003 王五 已支付 PROD-100这里面的逻辑是什么df[‘订单状态’] ‘已支付’这个操作会返回一个与df长度相同的布尔序列Series其中每个元素是True或False表示对应行的“订单状态”列是否等于“已支付”。然后将这个布尔序列传入df[...]中Pandas就会只返回那些对应位置为True的行。这是向量化操作在底层由C或Fortran优化速度极快远比用Python循环逐行判断要高效得多。注意操作符是大小写敏感的。如果数据中混入了“已支付”全角和“已支付”半角空格或者“YI ZHIFU”它们都不会被匹配到。数据清洗时的一致性检查至关重要。有时候我们的匹配条件不是单一的而是一个列表。比如我们想找出状态是“待发货”或“已取消”的订单。这时候就有点力不从心了你需要写(df[‘状态’] ‘A’) | (df[‘状态’] ‘B’)。对于这种情况.isin()方法是更优雅的选择。# 使用 .isin() 方法匹配多个精确值 status_to_filter [待发货, 已取消] filtered_orders df[df[订单状态].isin(status_to_filter)] print(filtered_orders)输出订单号 客户姓名 订单状态 产品代码 1 A002 李四 待发货 PROD-101 3 A004 赵六 已取消 PROD-102 4 A005 孙七 待发货 PROD-101.isin()同样执行的是完全匹配。它的内部实现也非常高效特别适合处理候选值较多的情况。2.2 避坑指南当“完全匹配”失灵时完全匹配的逻辑很清晰但为什么有时候代码明明看起来没错却筛不出数据呢根据我的经验90%的问题出在数据本身的不一致性上。坑1隐藏的空格或不可见字符。这是最经典的坑。数据可能来自不同的系统、手动录入或爬虫抓取经常在开头、结尾甚至中间夹杂着空格空格、制表符\t、换行符\n。比如数据库里的值是”已支付但你的CSV文件里读出来可能是” 已支付前面有个空格。用去匹配肯定失败。解决方案在匹配前先进行清洗。Pandas的.str访问器提供了.strip()、.lstrip()、.rstrip()方法来去除空格。# 假设数据有空格问题 df_dirty pd.DataFrame({状态: [ 已支付, 待发货 , \t已取消\n]}) print(df_dirty) # 输出 # 状态 # 0 已支付 # 1 待发货 # 2 已取消 # 直接匹配失败 print(df_dirty[df_dirty[状态] 已支付]) # 输出空DataFrame # 先去除首尾空白字符再匹配 df_clean df_dirty.copy() df_clean[状态] df_clean[状态].str.strip() print(df_clean[df_clean[状态] 已支付]) # 输出 # 状态 # 0 已支付坑2大小写问题。对于英文数据”Active“和”active“是完全不同的字符串。如果你的业务逻辑不区分大小写那么在匹配前需要统一大小写。df_case pd.DataFrame({Status: [Active, active, INACTIVE, Pending]}) # 统一转换为小写后再匹配 df_case_lower df_case.copy() df_case_lower[Status_lower] df_case_lower[Status].str.lower() print(df_case_lower[df_case_lower[Status_lower] active])坑3数据类型不是字符串。有时候你以为的“字符串”列可能实际上是数字类型int/float或者其他类型。对一个整数列使用.str访问器会直接抛出AttributeError。解决方案匹配前先用df[‘column’].dtype检查列的数据类型必要时用df[‘column’] df[‘column’].astype(str)进行转换。但要注意转换后数字1会变成字符串”1“可能会影响其他计算。个人心得我养成了一个习惯在开始任何基于字符串的筛选前先对目标列做一个快速的“数据快照”print(df[‘column’].unique()[:10])或者print(df[‘column’].value_counts(dropnaFalse).head(10))。这能帮你一眼发现数据里有没有奇怪的空格、特殊字符或者不一致的格式防患于未然。3. 部分匹配在模糊中寻找精确现实世界的数据很少像我们期望的那样整洁。更多的时候我们需要的是“模糊查找”。比如从用户反馈中找出所有提到“卡顿”的条目从日志文件中提取所有包含“Timeout”或“Error”的错误行从商品描述中筛选出所有“红色”的商品。这就是部分匹配的用武之地。Pandas为部分匹配提供了强大的.str.contains()方法。它的核心是检查序列中的每个字符串是否包含指定的子字符串。3.1.str.contains()的基本用法让我们用一个更贴近实际的例子假设我们有一个产品评论的DataFramereviews_data { review_id: [1, 2, 3, 4, 5], product: [手机X, 耳机Y, 手机X, 平板Z, 手机X], comment: [ 手机运行速度很快屏幕清晰。, 音质非常好佩戴舒适。, 电池续航有点短希望改进。, 看电影很爽但是有点重。, 系统偶尔会卡顿特别是玩游戏的时候。 ] } df_reviews pd.DataFrame(reviews_data)现在我们想找出所有评论中提到了“卡顿”这个词的条目。# 使用 .str.contains() 进行部分匹配 卡顿_reviews df_reviews[df_reviews[comment].str.contains(卡顿)] print(卡顿_reviews)输出review_id product comment 4 5 手机X 系统偶尔会卡顿特别是玩游戏的时候。很简单对吧.str.contains(‘卡顿’)返回一个布尔序列表示每条评论的字符串里是否含有“卡顿”这两个字。3.2 关键参数详解na,case,regex.str.contains()的强大之处在于它的参数这些参数让你能精细控制匹配行为。很多人只用默认参数其实错过了很多便利。na参数处理缺失值NaN。这是最容易出错的地方。默认情况下na参数是None在旧版本中是NaN这意味着如果某一行comment列的值是NaN空那么.str.contains()对它进行计算也会返回NaN。而在布尔索引中NaN会被当作False处理吗不它会导致该行被排除甚至可能引发警告。更稳妥的做法是明确指定naFalse。# 假设有一条评论是空的 df_reviews.loc[5] [6, 手机X, pd.NA] print(df_reviews[comment].str.contains(卡顿)) # 输出0 False, 1 False, ... 5 NA (dtype: object) # 如果直接用于筛选第5行索引5会因为值是NA而被静默排除行为不确定。 # 明确设置 naFalse将缺失值视为 False print(df_reviews[comment].str.contains(卡顿, naFalse)) # 输出0 False, 1 False, ... 5 False (dtype: bool) filtered_safe df_reviews[df_reviews[comment].str.contains(卡顿, naFalse)]case参数控制大小写敏感性。默认是True即区分大小写。对于英文搜索如果你不想区分”error“和”ERROR“就设置caseFalse。logs pd.DataFrame({message: [ERROR: Disk full, Warning: High CPU, error: connection timeout]}) # 区分大小写只能找到第一个 print(logs[logs[message].str.contains(ERROR)]) # 不区分大小写能找到第一个和第三个 print(logs[logs[message].str.contains(error, caseFalse)])regex参数正则表达式的开关。这是.str.contains()的灵魂所在默认是True。这意味着你传入的字符串会被当作正则表达式模式来解释。这既是强大的功能也是潜在的陷阱。3.3 当普通字符串遇到正则元字符一个常见的坑假设你的产品代码里包含点号.比如”PROD.100“。现在你想找出所有代码以”PROD.“开头的产品。新手可能会这么写df[产品代码] [PROD.100, PROD-101, PROD.200, TEST-001] # 错误写法点号 . 在正则里匹配任意字符 result df[df[产品代码].str.contains(PROD.)] print(result) # 这会匹配到 ‘PROD-101’因为 ‘.’ 匹配了 ‘-’在正则表达式中点号.是一个元字符代表“匹配任意单个字符除了换行符”。所以’PROD.‘这个模式会匹配”PROD1“、”PROD-“、”PRODA“等等。解决方案有两种转义元字符在正则表达式中在元字符前加反斜杠\来取消它的特殊含义。但在Python字符串里反斜杠本身也是转义符所以需要写成双反斜杠\\。# 正确写法1转义点号 result df[df[产品代码].str.contains(PROD\\.)] # 或者使用原始字符串更清晰 result df[df[产品代码].str.contains(rPROD\.)]关闭正则表达式如果你确定你的搜索模式就是简单的字面字符串不涉及任何正则功能可以将regex参数设为False。这样点号就只是一个普通的点号字符。# 正确写法2关闭正则进行纯文本查找 result df[df[产品代码].str.contains(PROD., regexFalse)]强烈建议除非你明确需要使用正则表达式的强大功能如.*、\d、[a-z]等否则在进行简单的部分匹配时养成设置regexFalse的习惯。这能让你的意图更清晰避免很多意想不到的匹配错误。我自己就曾因为一个未转义的括号’(‘在匹配版本号时匹配出了一堆乱码调试了半天。4. 正则表达式赋能解锁复杂模式匹配当你需要更灵活的匹配规则时比如“以‘ERR-’开头后跟3位数字”或者“包含‘电话’这个词但后面不能是‘推销’”简单的部分匹配就无能为力了。这时正则表达式Regex就是你的终极武器。.str.contains()在regexTrue默认时就能直接使用正则模式。4.1 几个实用的正则匹配场景让我们继续用产品评论的例子增加一些更复杂的需求。场景1匹配多种可能的关键词。我们想找出提到“电池”或“续航”的评论。# 使用正则的 “或” 操作符 | pattern_battery r电池|续航 battery_reviews df_reviews[df_reviews[comment].str.contains(pattern_battery)] print(battery_reviews[[review_id, comment]])r’电池|续航‘是一个原始字符串正则模式|表示“或”。这会匹配包含“电池”或包含“续航”的字符串。场景2匹配特定模式。假设评论中可能包含版本号如“V1.2.3”我们想提取所有包含版本号的评论。# 假设新增一条评论 df_reviews.loc[6] [7, App, 新版本V2.1.0修复了卡顿问题很好用。] pattern_version rV\d\.\d\.\d # 匹配 V数字.数字.数字 version_reviews df_reviews[df_reviews[comment].str.contains(pattern_version)] print(version_reviews[[review_id, comment]])这里\d匹配一个或多个数字\.匹配字面点号。这个模式能匹配V1.0.0、V10.2.345等。场景3更精确的匹配——单词边界。我们想找“快”这个评价但不希望匹配到“快递很快”里的“快”虽然这里也是正面评价但假设我们只想找单独形容速度的“快”。在正则中\b表示单词边界。pattern_fast r\b快\b # 匹配独立的“快”字 # 假设有一条评论是“快递很快点赞” df_reviews.loc[7] [8, 服务, 快递很快点赞] fast_reviews df_reviews[df_reviews[comment].str.contains(pattern_fast)] print(fast_reviews[[review_id, comment]]) # 这条可能匹配不到“快递很快”因为“快”不是独立单词。中文分词复杂\b可能不总是按预期工作这是一个需要注意的点。4.2 性能考量与实战技巧正则表达式功能强大但复杂度越高匹配速度通常越慢。对于海量数据数百万行以上使用复杂的正则进行逐行匹配可能会成为性能瓶颈。技巧1尽可能简化正则模式。避免使用过于宽泛或嵌套很深的模式。例如如果你只是想检查字符串是否以某个前缀开头用.str.startswith()比用正则r’^prefix‘更快更直观。# 更优选择使用 .str.startswith() df[df[产品代码].str.startswith(PROD-, naFalse)] # 而不是 df[df[产品代码].str.contains(r^PROD-, naFalse)]同理检查后缀用.str.endswith()检查是否完全由数字构成可以用.str.isnumeric()这些专门化的字符串方法在可能的情况下都应优先于正则使用。技巧2预编译正则表达式。如果你需要在同一个DataFrame的多个列上或者对多个DataFrame反复使用同一个复杂的正则模式可以使用Python的re模块进行预编译这能带来一定的性能提升。import re pattern re.compile(rERR-\d{3}) # 预编译模式ERR-后跟3位数字 # 使用时 df[df[log].apply(lambda x: bool(pattern.search(x)) if pd.notna(x) else False)]注意这里用了.apply()因为.str.contains()不接受编译好的正则对象。对于非常大的数据需要测试.apply与.str.contains的性能差异通常向量化的.str.contains更快但预编译在模式复杂且重复使用时可能有优势。技巧3对过滤后的数据应用正则。如果可能先用简单的条件如.str.contains(‘ERROR’, regexFalse)缩小数据范围再对这个小得多的数据集应用复杂的正则匹配。这能显著减少正则引擎需要处理的字符串数量。5. 多列匹配与复杂条件组合实际业务中筛选条件很少只基于一列。我们经常需要结合多个列的字符串匹配条件甚至混合字符串匹配与其他类型的条件如数值范围、日期。5.1 组合多个字符串匹配条件Pandas的布尔索引支持使用(与)、|(或)、~(非) 操作符来组合多个条件。非常重要的一点每个条件必须用括号()括起来因为运算符优先级问题。假设我们想从评论中找出产品是“手机X”并且评论中提到“卡顿”或“慢”的记录。# 定义条件 condition_product (df_reviews[product] 手机X) condition_performance (df_reviews[comment].str.contains(r卡顿|慢, naFalse)) # 组合条件产品是手机X AND (评论包含卡顿 OR 慢) # 注意对于“评论中提到‘卡顿’或‘慢’”我们已经在 condition_performance 中用正则的 | 实现了。 # 所以这里只需要 AND 连接两个条件。 final_condition condition_product condition_performance problematic_reviews df_reviews[final_condition] print(problematic_reviews)如果逻辑更复杂比如(产品是“手机X” 且 评论含“卡顿”)或(产品不是“手机X” 且 评论含“电池”)。condition1 (df_reviews[product] 手机X) (df_reviews[comment].str.contains(卡顿, naFalse)) condition2 (df_reviews[product] ! 手机X) (df_reviews[comment].str.contains(电池, naFalse)) complex_result df_reviews[condition1 | condition2]5.2 跨多列搜索同一字符串有时我们不确定目标字符串出现在哪一列需要在多个列里同时搜索。例如在客户信息表里我们想找所有包含“北京”的记录这个“北京”可能出现在“地址”列也可能出现在“公司”列甚至“备注”列。一种方法是分别对每列做判断然后用|连接。df_customer pd.DataFrame({ 姓名: [张三, 李四, 王五], 地址: [北京市海淀区, 上海浦东新区, 广州天河区], 公司: [上海科技, 北京分公司, 深圳创新] }) search_term 北京 condition (df_customer[地址].str.contains(search_term, naFalse)) | \ (df_customer[公司].str.contains(search_term, naFalse)) result df_customer[condition] print(result)如果列很多这样写会很冗长。可以使用.apply()结合axis1进行行方向的操作但性能上需要留意。# 对每一行检查‘地址’和‘公司’列组成的字符串是否包含‘北京’ condition df_customer[[地址, 公司]].apply( lambda row: row.astype(str).str.contains(search_term).any(), axis1 ) result df_customer[condition]这种方法更灵活但.apply(axis1)是逐行操作对于大数据集可能较慢。如果列数固定且不多第一种显式列出的方法向量化操作是更优选择。5.3 混合字符串与数值/日期条件筛选逻辑常常是混合的。比如找出“2023年以后下单”且“订单备注中包含‘加急’”的所有订单。# 假设 df_orders 有 ‘order_date’ (日期类型) 和 ‘note’ (字符串类型) 列 df_orders[order_date] pd.to_datetime(df_orders[order_date]) # 确保是日期类型 condition_date df_orders[order_date] 2023-01-01 condition_note df_orders[note].str.contains(加急, naFalse) urgent_orders_2023 df_orders[condition_date condition_note]这里的关键是确保每个子条件都返回一个布尔序列然后就可以用逻辑运算符自由组合。Pandas会很好地处理不同数据类型的比较。6. 性能优化与大数据集处理策略当数据量从几万行增长到几百万、几千万行时字符串匹配操作的效率就变得至关重要。一个不经意的低效操作可能让查询从秒级变成分钟甚至小时级。6.1 向量化操作是王道我之前强调过Pandas的.str访问器下的方法如.contains(),.startswith()以及比较运算符,!都是向量化操作。这意味着它们在整个数组上一次性执行底层由高度优化的C代码或NumPy实现。永远避免在Pandas中使用Python级别的循环如for loop或.apply()在某些场景下来逐行进行字符串匹配这是性能差异的数量级所在。6.2 使用.query()方法进行简洁查询对于复杂的多条件筛选除了用布尔索引和|~Pandas的.query()方法提供了一种更接近SQL的、可读性更高的语法。它同样支持向量化操作。# 使用 .query() 重写之前的复杂条件 # 原条件: (产品是“手机X” 且 评论含“卡顿”) 或 (产品不是“手机X” 且 评论含“电池”) # 注意.query() 中引用列名字符串需要用引号。这里用反引号包裹包含特殊字符中文、空格的列名是更安全的做法。 result_query df_reviews.query( (product 手机X and comment.str.contains(卡顿, naFalse)) or (product ! 手机X and comment.str.contains(电池, naFalse)), enginepython # 使用Python引擎以支持 .str 访问器 ) print(result_query).query()的优点是语法清晰尤其是条件非常多的时候。但需要注意默认的’numexpr‘引擎可能不支持所有Pandas功能如.str访问器有时需要指定engine’python‘这可能会损失一些性能优势。对于纯数值比较’numexpr‘引擎更快。6.3 考虑使用更底层的字符串方法对于超大规模数据如果.str.contains()仍然成为瓶颈可以考虑将数据转换为更底层的格式进行处理。例如转换为NumPy数组df[‘column’].values会得到一个NumPy数组。对于简单的相等匹配NumPy操作有时比Pandas Series操作稍快。但对于.contains()这类复杂操作优势不大因为Pandas底层也是调用的向量化字符串库。使用Python内置的in操作符与列表推导式谨慎使用对于较小的数据集或过滤后的小数据集列表推导式可能比.apply()快。但通常仍然不如向量化的.str.contains()。# 通常不推荐仅作对比 mask [search_term in str(x) for x in df[comment].fillna()] result df[mask]重要提示这种方法需要处理NaN用fillna(‘’)并且将每个元素转换为字符串str(x)在数据量大时可能更慢且失去了Pandas的优雅和安全性。6.4 终极策略索引与预计算如果某些字符串筛选条件是你业务中的高频操作比如经常要按“产品类别”或“错误类型”筛选那么最好的优化是在数据入库或ETL阶段就做好文章。建立分类索引如果一列的唯一值不多即基数低可以将其转换为category类型。Pandas对分类类型的某些操作有优化。df[product] df[product].astype(category) # 后续的 df[df[product] ‘手机X’] 可能会更快构建倒排索引对于全文搜索类需求如在大量文本中搜索多个关键词Pandas不是最佳工具。考虑使用专门的搜索引擎库如Whoosh或数据库如Elasticsearch。在Pandas层面可以预先将文本分词并建立一个“关键词-行索引”的映射字典但这属于更高级的定制化优化了。个人经验之谈在99%的场景下正确使用Pandas的向量化字符串操作.str.contains()withregexFalse.isin()已经足够快。性能问题的根源往往不在于此而在于读取了不必要的列用usecols参数只读需要的列。在循环中重复执行筛选将筛选条件提到循环外一次性计算好。数据本身过于庞大考虑使用Dask、Modin等库进行并行处理或者使用数据库。在优化之前一定要先用%timeit或line_profiler等工具定位真正的瓶颈所在避免过早和过度优化。7. 举一反三从“提取行”到“提取与替换”掌握了提取行的核心方法后我们可以很容易地将这些技术扩展到相关的字符串操作上其中.str.extract()和.str.replace()是两个非常强大的伙伴。7.1 使用.str.extract()提取匹配的子字符串有时候我们不仅想知道某一行是否包含特定模式还想把匹配到的具体内容提取出来形成新的一列。例如从杂乱的日志信息中提取出错误代码如”ERR-12345“或者从产品描述中提取出尺寸如”尺寸15.6英寸“。.str.extract()使用正则表达式的捕获组来提取子串。logs pd.DataFrame({ log_message: [ 2023-10-27 ERROR: Disk full on server A, code: ERR-507, 2023-10-27 INFO: Backup completed., 2023-10-28 WARNING: High memory usage, code: WARN-102, 2023-10-28 ERROR: Network timeout, code: ERR-408 ] }) # 定义正则模式用括号()表示要提取的捕获组 # 模式解释r‘code:\s*(\w-\d)’ # code: 匹配字面字符 # \s* 匹配0个或多个空白字符 # (\w-\d) 捕获组匹配一个或多个字母数字下划线接着一个‘-’接着一个或多个数字 pattern_extract rcode:\s*(\w-\d) error_codes logs[log_message].str.extract(pattern_extract) print(error_codes)输出0 0 ERR-507 1 NaN 2 WARN-102 3 ERR-408这样我们就得到了一列新的DataFrame包含了提取出的错误代码未匹配到的行显示为NaN。你可以通过.rename(columns{0: ‘error_code’})来重命名列。7.2 使用.str.replace()进行灵活的替换另一个常见需求是找到匹配的字符串后不是提取行而是将其替换掉。比如清理数据中的敏感信息如手机号、邮箱、统一格式、或移除不必要的字符。.str.replace()同样默认使用正则表达式。# 示例将日志中的错误代码替换为[CODE_REDACTED] logs[anonymized_log] logs[log_message].str.replace( pattern_extract, # 匹配模式 [CODE_REDACTED], # 替换成的字符串 regexTrue ) print(logs[[log_message, anonymized_log]].head())输出log_message anonymized_log 0 2023-10-27 ERROR: Disk full on server A, code... 2023-10-27 ERROR: Disk full on server A, [CODE_REDACTED] 1 2023-10-27 INFO: Backup completed. 2023-10-27 INFO: Backup completed. 2 2023-10-28 WARNING: High memory usage, code: ... 2023-10-28 WARNING: High memory usage, [CODE_REDACTED] 3 2023-10-28 ERROR: Network timeout, code: ERR-408 2023-10-28 ERROR: Network timeout, [CODE_REDACTED]关键参数regex和case和.contains()一样.replace()也有regex参数。如果你只是做简单的字面替换比如把所有的“win”换成“windows”务必设置regexFalse以避免正则元字符如点号.引起意外。case参数用于控制是否区分大小写。一个实用的清理技巧结合使用.str.replace()和正则表达式可以一次性清理掉字符串中所有非数字、非字母的字符只保留中文、英文、数字。df[clean_text] df[dirty_text].str.replace(r[^\w\u4e00-\u9fff], , regexTrue) # [^\w\u4e00-\u9fff] 匹配任何不是 单词字符、中文 Unicode 范围的字符并将其替换为空。从“筛选行”到“提取内容”再到“替换内容”这一套基于正则表达式的字符串处理组合拳能解决数据清洗和预处理中绝大多数文本相关的难题。核心思路都是一致的先定义模式精确文本或正则然后应用向量化操作。
郑州网站建设
网页设计
企业官网