You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas lambda内使用isin传字符串报错解决及索引匹配实现

问题说明

现有测试数据如下:

import pandas as pd
import numpy as np
    
Open_Time_s=['2022-04-30 11:05:00+03:00','2022-04-30 11:10:00+03:00', np.nan, np.nan]
intersect=[np.nan,np.nan,'intersect_2022-04-30 11:05:00+03:00','intersect_2022-04-30 11:10:00+03:00']
    
df = pd.DataFrame.from_dict({'Open Time':Open_Time_s,'intersect':intersect})
df['LEVEL']=np.nan

需求为逐行处理intersect列,去除前缀intersect_后匹配Open Time列的对应值,将匹配到的行索引写入LEVEL列,预期输出如下:

Open Time                        intersect  LEVEL
0  2022-04-30 11:05:00+03:00                              NaN    NaN
1  2022-04-30 11:10:00+03:00                              NaN    NaN
2                          NaN  intersect_2022-04-30 11:05:00+03:00    0.0
3                          NaN  intersect_2022-04-30 11:10:00+03:00    1.0

初始尝试代码:

df['LEVEL']=df['intersect'].loc[df['intersect'].isna()==0].apply(lambda x: df[df['Open Time'].isin(x.replace(r'intersect_', ''))].index)

触发报错only list-like objects are allowed to be passed to isin(), you passed a [str],原因是isin()方法仅接受可迭代的类列表对象作为入参,逐行apply时传入的是单个字符串,不符合参数要求。

解决方案

方法1:lambda逐行实现(符合要求)

逐行处理时不需要使用isin(),直接做等值判断即可。提前构建时间值到索引的映射字典可以避免每次apply都遍历全表,性能更好:

# 构建Open Time列非空值到行索引的映射
time_to_idx = {time: idx for idx, time in df['Open Time'].dropna().items()}

df['LEVEL'] = df['intersect'].apply(
    lambda val: time_to_idx.get(val.removeprefix('intersect_')) if pd.notna(val) else np.nan
)

如果不想提前构建映射,也可以直接在lambda中写匹配逻辑,仅适合小数据量场景:

df['LEVEL'] = df['intersect'].apply(
    lambda val: df.index[df['Open Time'] == val.removeprefix('intersect_')][0]
    if pd.notna(val) and (df['Open Time'] == val.removeprefix('intersect_')).any()
    else np.nan
)

注:Python 3.9+、Pandas 1.4.0+支持removeprefix()方法专门用于去除固定前缀,比replace更精准,不会误替换字符串中间的相同内容;低版本可以替换为val.replace('intersect_', '', 1),指定只替换1次匹配内容。

方法2:向量化实现(性能最优)

如果不强制要求使用lambda,优先选择pandas向量化操作,比逐行apply性能高3~10倍:

extracted_time = df['intersect'].str.removeprefix('intersect_')
time_to_idx = {time: idx for idx, time in df['Open Time'].dropna().items()}
df['LEVEL'] = extracted_time.map(time_to_idx)

运行上述任意一段代码,都可以得到预期的输出结果。

内容的提问来源于stack exchange,提问作者максим ильин

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 14:39:18