我可能误解了它是如何工作的。 鉴于此数据框架,我感到很惊讶:
A B C D
0 9.0 Nonnumeric 9.0
2 9.0 Num0a 9.0
此DOES似乎短路( - GOOD!):
dfzero["B"] = pd.DataFrame.where(
cond = dfzero["A"] != 0,
self = 1/dfzero["A"],
other = 0)
但这不是(--BAD!): (给出除零误差,因为没有短路):
df["D"] = pd.DataFrame.where(
cond = df["C"].str.len() == 5,
self = df["C"].str[-2:].apply(lambda x: int(x, 16)),
other = 0)
错误是:
self = (df["C"].str[-2:].apply(lambda x: int(x, 16))),
ValueError: invalid literal for int() with base 16: 'ic'
答案 0 :(得分:1)
不,即使第一种方法也不会短路。在计算结果之前,必须首先评估两个操作数。意思是,这是计算的,
i = dfzero["A"] != 0
i
0 False
1 True
Name: A, dtype: bool
这就是:
j = 1 / dfzero['A']
j
0 inf
1 0.500000
Name: A, dtype: float64
表达有效:
pd.DataFrame.where(i, j, 0)
第二个是相同的。行为是一致的。
您期待ZeroDivisionError
吗?你不会用numpy或pandas得到它,因为这些库假设你在计算这些数量时知道你在做什么。
此处的选项是预先计算掩码,然后仅计算这些行的结果。
m = df["C"].str.len() == 5
df['D'] = df.loc[m, 'C'].str[-2:].apply(lambda x: int(x, 16))
df
A B C D
0 0 9.0 Nonnumeric NaN
1 2 9.0 Num0a 10.0
如果您想填写NaN,请使用df.loc[~m, 'D'] = fill_value
。