解决Pandas中apply与lambda引发的TypeError: string indices must be integers错误
问题:Pandas修改列值时出现TypeError错误
我有如下Pandas DataFrame,需求为:当CompanyAd列包含"OTC+"或"OTC +"时,将Name列对应值修改为"ASD"。但运行以下代码时出现错误TypeError: string indices must be integers,请问该如何解决?
DataFrame定义代码
import pandas as pd from pandas import Timestamp dictA = {'Event_ID': {0: 'G-00001', 1: 'G-00002 ', 2: 'G-00003', 3: 'G-00004', 4: 'G-00005', 5: 'G-00006', 6: 'G-00007', 7: 'G-00008', 8: 'G-00009', 9: 'G-00010', 10: 'G-00011', 11: 'G-00012', 12: 'G-00013', 13: 'G-00014', 14: 'G-00015', 15: 'G-00016', 16: 'G-00017'}, 'Name': {0: 'ABC', 1: 'CSA', 2: 'CSA', 3: 'VSX', 4: 'ABC', 5: 'ABC', 6: 'CSA', 7: 'ABC', 8: 'VSX', 9: 'CSA', 10: 'VSX', 11: 'ABC', 12: 'VSX', 13: 'VSX', 14: 'ABC', 15: 'ABC', 16: 'CSA'}, 'CompanyAd ': {0: '51Job, Inc.Cayman Islands NMS ', 1: "724 Solution's Inc. Canada NMS ", 2: 'A B SKF Sweden OTC+ ', 3: 'A/S Steamship Company Torm Denmark"s NMS OTC+ ', 4: 'ABB Ltd. Switzerland OTC+ ', 5: 'Aber Diamond Ltd. Canada CAP MKT ', 6: 'Abitibi Consolidated Inc. Canada OTC + ', 7: 'ABN Amro Bank N.V. Netherlands AMEX - Preferred OTC+', 8: 'ABN Amro Holding N.V. Netherlands NYSE ', 9: 'Acambis plc United Kingdom OTC + ', 10: "Ace Aviation Holdings'aed Inc. Canada OTC ", 11: 'Acetex Corp. Canada OTC - Debt+ ', 12: 'Acrex Ventures, Ltd. Canada OTC+ ', 13: 'ACS-Tech 80 Ltd. Israel CAP MKT ', 14: 'Actions Semiconductor Co. Ltd. Cayman Islands NMS ', 15: 'Adastra Minerals Inc. Canada OTC* ', 16: 'ADB Systems International Inc. Canada OTC '}, 'ticket': {0: 671, 1: 5, 2: 5, 3: 23, 4: 4, 5: 60, 6: 60, 7: 89, 8: 0, 9: 6, 10: 3, 11: 2, 12: 4, 13: 32, 14: 3, 15: 1, 16: 23}, 'Revenue': {0: 6720, 1: 56, 2: 78, 3: 34, 4: 89, 5: 73, 6: 345, 7: 890, 8: 0, 9: 45, 10: 39, 11: 34, 12: 89, 13: 127, 14: 84, 15: 100, 16: 525}, 'Expences': {0: 150.0, 1: 18.0, 2: 38.0, 3: 23.0, 4: 150.0, 5: 55.0, 6: 110.0, 7: 150.0, 8: 0.0, 9: 16.0, 10: 23.0, 11: 150.0, 12: 48.0, 13: 35.0, 14: 55.0, 15: 150.0, 16: float('nan')}, 'expect': {0: 50.0, 1: 100.0, 2: 100.0, 3: float('nan'), 4: 40.0, 5: 60.0, 6: 60.0, 7: float('nan'), 8: 50.0, 9: 60.0, 10: 30.0, 11: 20.0, 12: 40.0, 13: 10.0, 14: 120.0, 15: 140.0, 16: 90.0}, 'Signed_Date': {0: Timestamp('2021-06-01 00:00:00'), 1: Timestamp('2021-06-05 00:00:00'), 2: Timestamp('2021-06-03 00:00:00'), 3: Timestamp('2021-06-03 00:00:00'), 4: Timestamp('2021-06-02 00:00:00'), 5: Timestamp('2021-04-15 00:00:00'), 6: Timestamp('2021-06-12 00:00:00'), 7: Timestamp('2021-06-02 00:00:00'), 8: Timestamp('2021-04-30 00:00:00'), 9: Timestamp('2021-06-22 00:00:00'), 10: Timestamp('2021-06-10 00:00:00'), 11: Timestamp('2021-06-03 00:00:00'), 12: Timestamp('2021-06-12 00:00:00'), 13: Timestamp('2021-04-24 00:00:00'), 14: Timestamp('2021-04-21 00:00:00'), 15: Timestamp('2021-06-07 00:00:00'), 16: Timestamp('2021-04-02 00:00:00')}} df = pd.DataFrame.from_dict(dictA)
报错的运行代码
df['account_name_e']=df['CompanyAd '].apply(str).str.replace(" ","") df['account_name_e'] = df['account_name_e'].apply(str).str.replace("(?i)[^0-9a-z+]",'') df['NameE'] = df['Name'] df['NameE'] = df['NameE'].apply(lambda row: str('ASD') if 'OTC+' in str(row['account_name_e']) else row) df
错误原因
df['NameE'].apply()中的lambda函数接收的是**NameE列的单个字符串元素**,而非整行数据。此时尝试用row['account_name_e']去索引字符串,自然会触发string indices must be integers错误——字符串只能用整数下标访问,不能用字典键。
解决方案
方法一:按行使用df.apply()
如果需要同时访问多列数据,可以用df.apply()并指定axis=1按行处理,此时lambda接收的是整行数据:
# 预处理CompanyAd列,生成account_name_e df['account_name_e'] = df['CompanyAd '].str.replace(" ", "").str.replace("(?i)[^0-9a-z+]", '') # 按行判断并赋值 df['NameE'] = df.apply(lambda row: 'ASD' if 'OTC+' in row['account_name_e'] else row['Name'], axis=1)
方法二:布尔索引直接修改(推荐,更高效)
Pandas的布尔索引比apply()性能更优,适合大数据集。直接用正则匹配原列生成掩码,再批量修改:
# 生成匹配掩码:匹配"OTC+"或"OTC +"(\s*匹配任意数量的空格) mask = df['CompanyAd '].str.contains(r'OTC\s*\+', regex=True, na=False) # 初始化NameE列为Name的副本 df['NameE'] = df['Name'].copy() # 对符合条件的行赋值为"ASD" df.loc[mask, 'NameE'] = 'ASD'
这种方法无需生成中间列account_name_e,直接匹配原列即可完成需求,代码更简洁高效。
内容的提问来源于stack exchange,提问作者rra
相关产品推荐
相关产品推荐

