pandas“where”功能似乎没有短路

时间:2018-02-20 04:40:26

标签: python pandas dataframe

我可能误解了它是如何工作的。 鉴于此数据框架,我感到很惊讶:

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'

1 个答案:

答案 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