如何基于可变列表在多列上迭代替代矢量化if/else逻辑?
解决方案:用循环实现多列匹配生成LT列
我明白你想要替换掉矢量化的np.where写法,改用循环来逐行检查ID和ID2列是否匹配ltlist里的ID值。下面是实现这个需求的代码,完全用循环来处理:
import pandas as pd ltlist = [1, 2] org = {'ID': [1, 3, 4, 5, 6, 7], 'ID2': [3, 4, 5, 6, 7, 2]} df = pd.DataFrame(org) # 初始化LT列默认值为0 df['LT'] = 0 # 遍历每一行进行匹配检查 for idx, row in df.iterrows(): # 先检查ID列是否在ltlist中 if row['ID'] in ltlist: df.at[idx, 'LT'] = row['ID'] # ID不匹配的话,检查ID2列 elif row['ID2'] in ltlist: df.at[idx, 'LT'] = row['ID2'] # 都不匹配就保持0(已经初始化过,这步可以省略,写出来更清晰) else: df.at[idx, 'LT'] = 0 print(df)
代码解释:
- 首先把原始字典转换成DataFrame,方便逐行处理
- 先给
LT列全部设为默认值0,避免后续重复赋值 - 用
iterrows()遍历每一行,获取行索引idx和当前行数据row - 按照需求的优先级:先判断
ID是否在目标列表ltlist中,匹配就把LT设为当前ID的值;如果不匹配,再判断ID2,匹配就设为ID2的值;都不匹配就保持0
运行这段代码后,输出结果和你期望的完全一致:
ID ID2 LT 0 1 3 1 1 3 4 0 2 4 5 0 3 5 6 0 4 6 7 0 5 7 2 2
另外提个小优化:如果ltlist的元素很多,把它转换成集合ltlist_set = set(ltlist)再做判断会更快,因为集合的in操作时间复杂度是O(1),列表是O(n)。修改后的判断部分可以写成:
ltlist_set = set(ltlist) for idx, row in df.iterrows(): if row['ID'] in ltlist_set: df.at[idx, 'LT'] = row['ID'] elif row['ID2'] in ltlist_set: df.at[idx, 'LT'] = row['ID2']
内容的提问来源于stack exchange,提问作者Tim Scongack
相关产品推荐
相关产品推荐

