为何DataFrame.insert插入整列字符串而非单个值?求解正确方法
问题
尝试执行以下代码向DataFrame插入名为DBREMOVECMD的列,期望每行生成对应自身NE_ID的delete语句:
df1ac.insert(0, column = "DBREMOVECMD", value = ("delete analog19_1.tp_table where NE_ID = " + str(df1ac["NE_ID"]) + " ;"))
执行前的DataFrame信息:
print(df1ac) LASTCOLLPER LASTCOLLECTIONPERIOD TimestampY FARK NE_ID 0 19700101000000 0 1675227525 1675227525 4135862 1 19700101000000 0 1675227525 1675227525 4135863 2 19700101000000 0 1675227525 1675227525 4135825 3 19700101000000 0 1675227525 1675227525 4135824 df1ac.info() <class 'pandas.core.frame.DataFrame'> RangeIndex: 4 entries, 0 to 3 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 LASTCOLLPER 4 non-null int64 1 LASTCOLLECTIONPERIOD 4 non-null int64 2 TimestampY 4 non-null int64 3 FARK 4 non-null int64 4 NE_ID 4 non-null int64 dtypes: int64(5) memory usage: 288.0 bytes
执行后,DBREMOVECMD列每个单元格都包含整个NE_ID列的字符串形式,而非对应行的单个值,输出如下:
print(df1ac) DBREMOVECMD ... NE_ID 0 delete analog19_1.tp_table where NE_ID = 0 ... ... 4135862 1 delete analog19_1.tp_table where NE_ID = 0 ... ... 4135863 2 delete analog19_1.tp_table where NE_ID = 0 ... ... 4135825 3 delete analog19_1.tp_table where NE_ID = 0 ... ... 4135824 [4 rows x 6 columns] df1ac.info() <class 'pandas.core.frame.DataFrame'> RangeIndex: 4 entries, 0 to 3 Data columns (total 6 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 DBREMOVECMD 4 non-null object 1 LASTCOLLPER 4 non-null int64 2 LASTCOLLECTIONPERIOD 4 non-null int64 3 TimestampY 4 non-null int64 4 FARK 4 non-null int64 5 NE_ID 4 non-null int64 dtypes: int64(5), object(1) memory usage: 320.0+ bytes print(df1ac.loc[0].DBREMOVECMD) delete analog19_1.tp_table where NE_ID = 0 4135862 1 4135863 2 4135825 3 4135824 Name: NE_ID, dtype: int64 ; print(df1ac.loc[1].DBREMOVECMD) delete analog19_1.tp_table where NE_ID = 0 4135862 1 4135863 2 4135825 3 4135824 Name: NE_ID, dtype: int64 ;
请问为何使用DataFrame.insert命令时,插入的是整列字符串而非单个值?如何修改代码实现预期效果?
原因分析
问题出在str(df1ac["NE_ID"])这一步:df1ac["NE_ID"]是一个pandas Series对象,直接用str()转换会把整个Series的完整字符串表示(包含所有行的索引和值)拼接进去,而非逐行转换每个元素。最终生成的是一个固定的长字符串,insert操作会把这个字符串广播到每一行,导致每个单元格内容完全一致,都是整个NE_ID列的内容。
解决方案
需要对Series的每个元素单独进行字符串拼接,以下是几种常用实现方式:
方法1:向量化字符串拼接
先将NE_ID列转为字符串类型,再和固定前后缀进行向量化拼接,效率最高:
# 构造命令列 delete_cmds = "delete analog19_1.tp_table where NE_ID = " + df1ac["NE_ID"].astype(str) + " ;" # 插入到第0列 df1ac.insert(0, column="DBREMOVECMD", value=delete_cmds)
方法2:apply逐行处理
通过apply对NE_ID列的每个元素执行格式化操作:
df1ac.insert(0, column="DBREMOVECMD", value=df1ac["NE_ID"].apply(lambda x: f"delete analog19_1.tp_table where NE_ID = {x} ;"))
方法3:整行apply格式化
如果需要基于多列生成命令,可使用整行apply的方式:
df1ac.insert(0, column="DBREMOVECMD", value=df1ac.apply(lambda row: f"delete analog19_1.tp_table where NE_ID = {row['NE_ID']} ;", axis=1))
执行以上任意一种方法后,DBREMOVECMD列的每个单元格都会对应自身行的NE_ID值,比如第0行内容为delete analog19_1.tp_table where NE_ID = 4135862 ;,符合预期。
内容的提问来源于stack exchange,提问作者saluc
相关产品推荐
相关产品推荐

