使用Pandas apply lambda带条件填充列时遇TypeError求助
问题分析与解决方法
错误原因
你的代码存在两个核心问题:
apply作用对象错误:调用df['AdjPrice'].apply()时,lambda函数的参数x是AdjPrice列的单个元素(当前为空字符串),并非整行数据,因此x['Timestamp']会触发TypeError——字符串无法用列名作为索引。- 日期类型未统一:
Timestamp列还是字符串格式,直接与mydate(datetime对象)比较会导致逻辑错误,必须先将其转换为datetime类型才能正确比较日期大小。
正确实现方案
以下是三种高效的实现方式,优先推荐方法二和方法三(性能优于逐行apply):
方法1:逐行处理(apply指定axis=1)
import pandas as pd # 1. 将Timestamp列转换为datetime类型,匹配格式定义 df['Timestamp'] = pd.to_datetime(df['Timestamp'], format='%d/%m/%Y') # 2. 定义目标日期 mydate = pd.to_datetime("1/5/2022", format='%d/%m/%Y') # 3. 逐行处理,axis=1表示按行传递数据 df['AdjPrice'] = df.apply(lambda row: row['Price'] * 0.15 if row['Timestamp'] < mydate else row['Price'], axis=1)
方法2:向量化处理(numpy.where,性能最优)
import pandas as pd import numpy as np # 统一日期类型 df['Timestamp'] = pd.to_datetime(df['Timestamp'], format='%d/%m/%Y') mydate = pd.to_datetime("1/5/2022", format='%d/%m/%Y') # 向量化条件赋值,避免逐行循环 df['AdjPrice'] = np.where(df['Timestamp'] < mydate, df['Price'] * 0.15, df['Price'])
方法3:分片赋值(loc索引)
import pandas as pd # 统一日期类型 df['Timestamp'] = pd.to_datetime(df['Timestamp'], format='%d/%m/%Y') mydate = pd.to_datetime("1/5/2022", format='%d/%m/%Y') # 先给所有行默认赋值Price df['AdjPrice'] = df['Price'] # 对符合条件的行更新值 df.loc[df['Timestamp'] < mydate, 'AdjPrice'] = df['Price'] * 0.15
最终效果
执行后AdjPrice列会被正确填充:
| Product | Price | Timestamp | AdjPrice |
|---|---|---|---|
| A1 | 1142 | 2022-03-01 | 171.3 |
| A1 | 1148 | 2022-04-01 | 172.2 |
| A1 | 1177 | 2022-05-01 | 1177 |
| A1 | 1163 | 2022-06-01 | 1163 |
| A1 | 1160 | 2022-07-01 | 1160 |
内容的提问来源于stack exchange,提问作者GMT
相关产品推荐
相关产品推荐

