如何基于行条件高效更新DataFrame单元格(动态+静态查询)
问题描述
原始DataFrame:
+----+------------------------------------------------+-------------+----------+----------+ | | String | Substring | Result 1 | Result 2 | +----+------------------------------------------------+-------------+----------+----------+ | 0 | fooDisplay "screen 1" other text | Screen 1 | | | | 1 | foobar Display "Screen2" more text | GFX | | | | 2 | barDisplay "Screen2"useless text | Screen 2 | | | | 3 | Link="Screen 1" | Screen 1 | | | +----+------------------------------------------------+-------------+----------+----------+
期望得到的DataFrame:
+----+------------------------------------------------+-------------+----------+----------+ | | String | Substring | Result 1 | Result 2 | +----+------------------------------------------------+-------------+----------+----------+ | 0 | foo"Display screen 1" other text | Screen 1 | True | False | | 1 | foobar Display "Screen2" more text | GFX | False | False | | 2 | barDisplay "Screen2"useless text | Screen 2 | False | True | | 3 | Link="Screen 1" | Screen 1 | False | False | +----+------------------------------------------------+-------------+----------+----------+
核心逻辑:
- 构造搜索字符串:
'Display ' + 该行Substring,不区分大小写检查String列是否包含该字符串,是则Result 1为True,否则False - 构造搜索字符串:
'Display "' + 该行Substring + '"',不区分大小写检查String列是否包含该字符串,是则Result 2为True,否则False
由于DataFrame数据量可达数十万行,且可能需要生成多达10个类似Result的列,需避免逐行迭代,采用Python高效实践实现。
高效解决方案
利用pandas的矢量化操作(内部基于C级循环,远快于Python原生逐行迭代),可以通过apply方法结合自定义逻辑批量处理,或者直接使用字符串方法的矢量化特性实现。
方法1:单列直接赋值(适合少量Result列)
直接针对每个Result列构造条件,使用apply逐行处理(此方法是pandas优化后的操作,性能远优于手动for循环):
import pandas as pd # 假设原始数据已存入df df['Result 1'] = df.apply( lambda row: ('Display ' + row['Substring']).lower() in row['String'].lower(), axis=1 ) df['Result 2'] = df.apply( lambda row: ('Display "' + row['Substring'] + '"').lower() in row['String'].lower(), axis=1 )
方法2:封装函数批量处理(适合多个Result列)
如果需要生成多个Result列,将所有检查逻辑封装成函数,一次性返回所有结果,代码更简洁易维护:
def check_all_conditions(row): # Result 1 逻辑 search1 = 'Display ' + row['Substring'] res1 = search1.lower() in row['String'].lower() # Result 2 逻辑 search2 = f'Display "{row["Substring"]}"' res2 = search2.lower() in row['String'].lower() # 可继续添加更多Result列的检查逻辑 # res3 = ... # 返回所有结果,对应列名 return pd.Series([res1, res2], index=['Result 1', 'Result 2']) # 批量赋值给多个列 df[['Result 1', 'Result 2']] = df.apply(check_all_conditions, axis=1)
关键优化点
- 避免手动for循环:pandas的
apply(axis=1)内部是优化后的迭代,性能比Python原生for循环提升数倍 - 大小写不敏感处理:通过统一转小写(
.lower())实现,比使用正则忽略大小写更高效 - 批量处理:多Result列时用函数封装,减少重复代码,提升可维护性
内容的提问来源于stack exchange,提问作者kubiej21
相关产品推荐
相关产品推荐

