Pandas循环赋值问题:Test列全行被覆盖而非对应行赋值
解析瑞士IBAN时Pandas列被循环结果覆盖的问题解决
问题描述
我用Python解析银行XML账单,用Pandas处理数据时遇到了问题。原本想让匹配到瑞士IBAN的行在Test列填入对应IBAN,未匹配的行填None,但循环最后一次的结果覆盖了整个Test列——比如2条数据里,第一行无匹配却被设成了第二行的IBAN。循环的索引i和getlength数值是对的,怀疑是混淆了普通循环和Pandas的数据操作逻辑。
原问题代码
for i in range(0, getlength): result = str(dd['entry_details'][i]) search_for_iban = re.search("CH\d{2}[ ]\d{4}[ ]\d{4}[ ]\d{4}[ ]\d{4}[ ]\d{1}|CH\d{19}", result) if(search_for_iban is None): df['Test'] = 'None' else: df['Test'] = search_for_iban.group() all_entries.append(df)
问题分析
你的问题核心是直接对整个df['Test']列赋值,而非针对单行操作。每次循环都会把整个Test列替换为当前循环的结果,最后一次循环的赋值会覆盖之前所有操作,导致全列都是最后一次循环的匹配结果(或None)。
解决方案
方案1:修正循环逻辑(针对单行赋值)
先初始化Test列为None,然后通过df.loc[i, 'Test']仅修改当前行的值:
# 初始化Test列为None df['Test'] = None for i in range(getlength): result = str(dd['entry_details'][i]) search_for_iban = re.search(r"CH\d{2}[ ]\d{4}[ ]\d{4}[ ]\d{4}[ ]\d{4}[ ]\d{1}|CH\d{19}", result) if search_for_iban is not None: # 仅修改第i行的Test列 df.loc[i, 'Test'] = search_for_iban.group() all_entries.append(df)
方案2:使用Pandas矢量化操作(推荐)
Pandas原生支持字符串矢量化处理,无需循环,效率更高且代码更简洁:
# 定义瑞士IBAN正则表达式 iban_pattern = r"(CH\d{2}[ ]\d{4}[ ]\d{4}[ ]\d{4}[ ]\d{4}[ ]\d{1}|CH\d{19})" # 将entry_details转为字符串后提取IBAN,无匹配则为NaN df['Test'] = dd['entry_details'].astype(str).str.extract(iban_pattern, expand=False) # 可选:将NaN替换为字符串'None' df['Test'] = df['Test'].fillna('None') all_entries.append(df)
为什么推荐矢量化操作?
Pandas的设计初衷就是高效处理批量数据,矢量化操作比逐行循环的执行速度快得多(数据量越大差距越明显),同时代码更简洁,避免了循环中容易出现的索引错误。
内容的提问来源于stack exchange,提问作者plumped
相关产品推荐
相关产品推荐

