如何在Pandas DataFrame中按指定模式匹配并替换单元格内容
问题描述
我有一个包含字符串、整数和浮点数的DataFrame,示例如下:
| Date | Col 1 | Col 2 | Col 3 | Col 3 | Col 4 | Col 5 | Col 6 |
|---|---|---|---|---|---|---|---|
| 09/2023 | 181.70 | 17.70 / 22.22 | 14.40 | 109.00 | NaN | 6 | 0 / NTD |
| 06/2023 | 143.60 | 17.00 | 15.30 | 190.05 | NaN | 6 / 11.41 | 1 |
| 03/2023 | 5 / 18.68 | NC / 17.67 | NC / 30.02 | NaN | NaN | 5 / NTD | NC / 2 |
需要为每行应用三个替换条件(条件1需优先执行):
- 若单元格内容为「数字 / 数字」,则替换为"Division";
- 若单元格内容为「NC / 数字」,则替换为"No changes";
- 若单元格内容为「数字 / NTD」,则替换为"No ToDo's";
所有修改需在原DataFrame中完成,预期输出示例如下:
| Date | Col 1 | Col 2 | Col 3 | Col 3 | Col 4 | Col 5 | Col 6 |
|---|---|---|---|---|---|---|---|
| 09/2023 | 181.70 | Division | 14.40 | 109.00 | NaN | 6 | No ToDo's |
| 06/2023 | 143.60 | 17.00 | 15.30 | 190.05 | NaN | Division | 1 |
| 03/2023 | Division | No changes | No changes | NaN | NaN | No ToDo's | No changes |
我尝试实现了条件2的代码:
for k in range(0, df.shape[1]): for m,p in enumerate(df[df.columns[(k)]]): if (p == ("<NC> / ")): df[df.columns[k]][m] = df[df.columns[k]][m].replace(p, 'No changes')
类似地,条件3的实现也较为顺利,但条件1需要优先执行(不能放在if的else分支中),且我不知道如何匹配「/」前后任意数字的情况,希望得到帮助。
解决方案
直接用pandas的replace方法结合正则表达式就能高效解决,既保证条件优先级,又无需低效的嵌套循环:
import pandas as pd # 假设你的DataFrame是df # 定义替换规则,顺序决定优先级:条件1优先,再是条件2、3 replace_rules = [ # 条件1:匹配整数/小数 + 空格/空格 + 整数/小数 (r'^\d+(\.\d+)?\s/\s\d+(\.\d+)?$', 'Division'), # 条件2:匹配 NC + 空格/空格 + 整数/小数 (r'^NC\s/\s\d+(\.\d+)?$', 'No changes'), # 条件3:匹配整数/小数 + 空格/空格 + NTD (r'^\d+(\.\d+)?\s/\sNTD$', "No ToDo's") ] # 对所有列应用替换,inplace=True直接修改原DataFrame df.replace(replace_rules, regex=True, inplace=True)
代码说明:
- 正则表达式中的
^和$确保匹配整个单元格内容,避免部分匹配(比如不会误改包含类似格式的长字符串);\d+(\.\d+)?可以匹配整数或小数;\s/\s匹配中间带空格的斜杠。 replace方法按列表顺序依次匹配替换,所以条件1会优先执行,符合需求。inplace=True直接修改原DataFrame,不需要额外赋值。
为什么不用循环?
你之前的嵌套循环效率极低,尤其是数据量大时。pandas的矢量化操作(如replace)是基于底层C实现的,速度快得多,代码也更简洁易维护。
内容的提问来源于stack exchange,提问作者Supernova
相关产品推荐
相关产品推荐

