You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python/Pandas中更新存在于另一个DataFrame中的指定行

Pandas批量更新DataFrame行(对应SQL UPDATE逻辑)

要实现你需要的基于id的批量更新,不用逐行循环,Pandas的loc结合布尔索引是最适合的方案——比at更贴合你基于列值(而非索引位置)的更新需求,而且性能远高于循环或列表推导。

下面是对应你三个SQL语句的Pandas实现:

1. 标记"Active Customer"(对应第一个UPDATE)

筛选user_id存在于logs且不为空的行,更新status:

# 条件:user_id不为空 且 在logs的user_id列表中
mask_active = users_df['user_id'].notna() & users_df['user_id'].isin(logs['user_id'])
users_df.loc[mask_active, 'status'] = 'Active Customer'

2. 标记"Non Active Customer"(对应第二个UPDATE)

筛选user_id不在logs、不为空且当前status为Unknown的行:

# 条件:user_id不为空 + 不在logs列表中 + status仍为Unknown
mask_non_active = users_df['user_id'].notna() & ~users_df['user_id'].isin(logs['user_id']) & (users_df['status'] == 'Unknown')
users_df.loc[mask_non_active, 'status'] = 'Non Active Customer'

3. 标记"Active Customer (Calls)"(对应第三个UPDATE)

先构造calls测试数据,再筛选符合条件的行:

# 构造calls测试DF
calls = pd.DataFrame({'user_id': ['50', '32']})
calls["user_id"] = pd.to_numeric(calls["user_id"])

# 条件:user_id>0 + 在calls列表中 + status仍为Unknown
mask_calls_active = (users_df['user_id'] > 0) & users_df['user_id'].isin(calls['user_id']) & (users_df['status'] == 'Unknown')
users_df.loc[mask_calls_active, 'status'] = 'Active Customer (Calls)'

完整示例代码

替换你原来的更新部分,完整代码如下:

import pandas as pd
import numpy as np

# 创建测试用户DF
users_df = pd.DataFrame(
{'name':['Bob','Olivia','Gustav','Bella', 'Fran', 'Marco'],
 'user_id':['10',np.nan,'30','50','32',np.nan]
}
)
users_df["user_id"] = pd.to_numeric(users_df["user_id"])
users_df['status'] = 'Unknown'

# 创建logs测试DF
logs = pd.DataFrame(
{'user_id':['10','20','30','32','55']}
)
logs["user_id"] = pd.to_numeric(logs["user_id"])

# 1. 更新Active Customer
mask_active = users_df['user_id'].notna() & users_df['user_id'].isin(logs['user_id'])
users_df.loc[mask_active, 'status'] = 'Active Customer'

# 2. 更新Non Active Customer
mask_non_active = users_df['user_id'].notna() & ~users_df['user_id'].isin(logs['user_id']) & (users_df['status'] == 'Unknown')
users_df.loc[mask_non_active, 'status'] = 'Non Active Customer'

# 3. 更新Active Customer (Calls)
calls = pd.DataFrame({'user_id': ['50', '32']})
calls["user_id"] = pd.to_numeric(calls["user_id"])
mask_calls_active = (users_df['user_id'] > 0) & users_df['user_id'].isin(calls['user_id']) & (users_df['status'] == 'Unknown')
users_df.loc[mask_calls_active, 'status'] = 'Active Customer (Calls)'

print(users_df)

为什么不用df.at?

df.at是用来定位单个元素的语法(需要指定索引位置+列名),适合修改单个值;而你需要批量更新符合条件的多行,loc支持布尔筛选,能高效完成批量操作,完全匹配你SQL中WHERE条件的逻辑,性能也比循环或列表推导好很多。

内容的提问来源于stack exchange,提问作者thenewbie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 05:22:44