如何用Pandas向量化实现用另一列值替换某列子串
问题:向量化替换Pandas DataFrame中XML字符串的子串
我有一个Pandas DataFrame,其中一列是XML字符串(XML列),另一列(ICCID列)存储着需要逐行替换XML列中子串的值。尝试用向量化方式实现该操作,编写了以下代码:
import pandas as pd pd.set_option('display.max_columns', None) pd.set_option('display.max_colwidth', None) pd.set_option('display.max_rows', None) pd.set_option('display.expand_frame_repr', False) columns = ['MSISDN', 'XML', 'ICCID', 'IMSI'] data = [['0123456789', '<subscriberInfo><msisdn>0123456789</msisdn><iccId>12345678998765432100</iccId><imsi>112233445566778</imsi><serviceProviderId>x</serviceProviderId><paymentType>POSTPAID</paymentType></subscriberInfo>', 89410123456789123456, 112233445566778], ['9876543210', '<subscriberInfo><msisdn>9876543210</msisdn><iccId>98765432112365478900</iccId><imsi>998877665544332</imsi><serviceProviderId>x</serviceProviderId><paymentType>POSTPAID</paymentType></subscriberInfo>', 89410987654321987456, 228024357302211], ['0123987456', '<subscriberInfo><msisdn>0123987456</msisdn><iccId>98765432198765432100</iccId><imsi>665544998877332</imsi><serviceProviderId>x</serviceProviderId><paymentType>POSTPAID</paymentType></subscriberInfo>', 89410987654321098765, 228024357302212]] df = pd.DataFrame(data=data, columns=columns) df['NEW_XML'] = df['XML'].replace(to_replace=[r'<iccId>\d{20}</iccId>'], value=[fr'<iccId>{df["ICCID"]}</iccId>'], regex=True)
但该方法无法正常工作,XML字符串中的目标子串被替换成了Pandas Series的完整字符串表示,示例如下:
0 89410123456789123456 1 89410987654321987456 2 89410987654321098765 Name: ICCID, dtype: object
期望的NEW_XML列结果如下:
NEW_XML '<subscriberInfo><msisdn>0123456789</msisdn><iccId>89410123456789123456</iccId><imsi>112233445566778</imsi><serviceProviderId>x</serviceProviderId><paymentType>POSTPAID</paymentType></subscriberInfo>' '<subscriberInfo><msisdn>9876543210</msisdn><iccId>89410987654321987456</iccId><imsi>998877665544332</imsi><serviceProviderId>x</serviceProviderId><paymentType>POSTPAID</paymentType></subscriberInfo>' '<subscriberInfo><msisdn>0123987456</msisdn><iccId>89410987654321098765</iccId><imsi>665544998877332</imsi><serviceProviderId>x</serviceProviderId><paymentType>POSTPAID</paymentType></subscriberInfo>'
解决方案
问题根源:使用df['XML'].replace()时,value参数传入的格式化字符串直接引用了整个df["ICCID"] Series,Pandas会将该Series对象转换成字符串插入,而非逐行取对应的值。
以下是两种可行的向量化实现方式:
方法1:用apply逐行处理(简洁直观)
通过apply遍历每一行,针对每行的XML字符串和ICCID值完成替换:
df['NEW_XML'] = df.apply(lambda row: row['XML'].replace(r'<iccId>\d{20}</iccId>', f'<iccId>{row["ICCID"]}</iccId>'), axis=1)
方法2:用str.replace配合Series.map(更贴近纯向量化)
先通过map为每个ICCID生成对应的替换模板字符串,再用str.replace完成批量替换:
# 生成替换模板 replace_str = df['ICCID'].map(lambda x: f'<iccId>{x}</iccId>') # 批量替换XML中的目标子串 df['NEW_XML'] = df['XML'].str.replace(r'<iccId>\d{20}</iccId>', replace_str, regex=True)
运行任意一种方法后,都能得到符合预期的NEW_XML列。
内容的提问来源于stack exchange,提问作者urosdigital
相关产品推荐
相关产品推荐

