基于DataFrame每行函数返回值新增3列:解决键长度错误
问题原因及解决方法
你遇到的键长度错误,核心问题是**rangeChecker函数返回pd.Series的方式完全错误**:
- 你写的
pd.Series("True", row['IPBlock'], row['Site']),实际是把第一个参数当数据,后两个当成了Series的索引,返回的是长度为1的Series,而你需要3个值,自然和目标列的3个键不匹配。 - 最后返回的
pd.Series("False" "NA" "NA")更糟,三个字符串连写会被Python自动拼接成一个字符串"FalseNANA",返回的还是长度1的Series,同样不满足需求。
另外还有几个隐性问题:
foundIps是全局变量,但没初始化,会触发NameError。dfa变量在rangeChecker里被使用,但未定义,得确保它是全局变量或通过参数传入。- 用到的
IPAddress和IPNetwork需要导入ipaddress模块。
修正后的代码
import pandas as pd import ipaddress # 初始化全局变量 foundIps = 0 # 假设dfa是提前定义好的IP块数据集,比如从文件读取 dfa = pd.read_csv('IPBlocks.csv') def mainRun(): df = pd.read_csv('SomeCSV.csv') df['IP'] = df['IP'].fillna("0.0.0.0") try: # apply返回的结果会自动展开为3列,对应指定的列名 df[['MatchFound', 'IPBlock', 'Site']] = df.apply(lambda row: rangeChecker(row['IP']), axis=1) except Exception as e: print(f"IPs found --> {foundIps}") print(f"Error {e}") def rangeChecker(rip): global foundIps ripList = rip.splitlines() for i in ripList: for _, row in dfa.iterrows(): try: # 添加strict=False避免IP块格式严格校验报错 if ipaddress.ip_address(i) in ipaddress.ip_network(row['IPBlock'], strict=False): foundIps += 1 # 将三个值放入列表,返回长度为3的Series return pd.Series([True, row['IPBlock'], row['Site']]) except Exception as e: # 捕获具体错误,避免单个IP出错就终止整个检查 print(f"检查IP {i}时出错: {e}") continue # 未匹配到的情况返回三个默认值 return pd.Series([False, "NA", "NA"])
关键修正点
- 返回
pd.Series时,把三个值放在列表/元组中,确保Series长度为3,和目标列数量一致。 - 修复字符串拼接错误:将
"False" "NA" "NA"改为[False, "NA", "NA"](用布尔值更规范)。 - 导入必要的
ipaddress模块,调用时使用完整的模块方法名,并添加strict=False适配更多IP块格式。 - 提前初始化全局变量
foundIps,避免未定义错误。 - 将
dfa.iterrows()中的index改为_(用下划线占位不需要的变量),并把循环里的break改为continue,避免单个IP出错就终止整个检查流程。
内容的提问来源于stack exchange,提问作者NullWolf
相关产品推荐
相关产品推荐

