Pandas如何基于历史行数据逐行计算玩家实时距离并解决相关报错?
报错原因
你遇到的ValueError是因为在if判断中直接使用了Pandas Series对象做布尔运算,Pandas无法判断你需要校验序列的全部元素为真还是任意元素为真,因此抛出歧义错误。通常是因为判断条件错误引用了整个DataFrame的列,而非遍历过程中的单行标量值。
推荐实现方案
优先使用向量化操作实现需求,性能远高于iterrows遍历,尤其适合大体积的事件日志数据。
实现逻辑
- 分别为两名目标玩家生成专属坐标列:仅当对应玩家触发
PlayerMoveEvent时赋值,其余行填充NaN - 对专属坐标列做向前填充(
ffill),使每一行都能获取到两名玩家的最新坐标 - 基于填充后的坐标直接批量计算三维欧氏距离
代码示例
import pandas as pd import numpy as np # 替换为你需要计算的两名目标玩家ID TARGET_PLAYERS = ["player_a", "player_b"] # 生成两名玩家的专属坐标列,非移动事件/非目标玩家行填充NaN df["p1_x"] = np.where((df["player"] == TARGET_PLAYERS[0]) & (df["event"] == "PlayerMoveEvent"), df["location_x"], np.nan) df["p1_y"] = np.where((df["player"] == TARGET_PLAYERS[0]) & (df["event"] == "PlayerMoveEvent"), df["location_y"], np.nan) df["p1_z"] = np.where((df["player"] == TARGET_PLAYERS[0]) & (df["event"] == "PlayerMoveEvent"), df["location_z"], np.nan) df["p2_x"] = np.where((df["player"] == TARGET_PLAYERS[1]) & (df["event"] == "PlayerMoveEvent"), df["location_x"], np.nan) df["p2_y"] = np.where((df["player"] == TARGET_PLAYERS[1]) & (df["event"] == "PlayerMoveEvent"), df["location_y"], np.nan) df["p2_z"] = np.where((df["player"] == TARGET_PLAYERS[1]) & (df["event"] == "PlayerMoveEvent"), df["location_z"], np.nan) # 向前填充NaN,获取每一行对应的玩家最新坐标 df[["p1_x", "p1_y", "p1_z", "p2_x", "p2_y", "p2_z"]] = df[["p1_x", "p1_y", "p1_z", "p2_x", "p2_y", "p2_z"]].ffill() # 计算三维欧氏距离 df["dist"] = np.sqrt( (df["p2_x"] - df["p1_x"])**2 + (df["p2_y"] - df["p1_y"])**2 + (df["p2_z"] - df["p1_z"])**2 ) # 清理临时生成的坐标列 df = df.drop(columns=["p1_x", "p1_y", "p1_z", "p2_x", "p2_y", "p2_z"])
iterrows遍历的正确写法
如果你坚持使用遍历方式,可参考以下规避报错的实现:
import pandas as pd import numpy as np TARGET_PLAYERS = ["player_a", "player_b"] # 可根据实际业务修改两名玩家的初始坐标 p1_pos = [0.0, 0.0, 0.0] p2_pos = [0.0, 0.0, 0.0] dist_list = [] for idx, row in df.iterrows(): # 直接取当前行的标量值做判断,不会触发Series布尔歧义错误 if row["player"] == TARGET_PLAYERS[0] and row["event"] == "PlayerMoveEvent": p1_pos = [row["location_x"], row["location_y"], row["location_z"]] elif row["player"] == TARGET_PLAYERS[1] and row["event"] == "PlayerMoveEvent": p2_pos = [row["location_x"], row["location_y"], row["location_z"]] # 计算当前距离 current_dist = np.sqrt((p2_pos[0]-p1_pos[0])**2 + (p2_pos[1]-p1_pos[1])**2 + (p2_pos[2]-p1_pos[2])**2) dist_list.append(current_dist) df["dist"] = dist_list
注意:遍历方案在数据量超过1万行时性能会明显下降,优先使用向量化方案。
内容的提问来源于stack exchange,提问作者Robert McManus
相关产品推荐
相关产品推荐

