Tengo dos fragmentos de código de pandas que creo que deberían ser equivalentes, pero el segundo no hace lo que espero.
# snippet 1 data = all_data[[((np.isfinite(all_data[self.design_metric][i]) and all_data['Source'][i] == 2)) or ((np.isfinite(all_data[self.actual_metric][i]) and all_data['Source'][i] != 2)) for i in range(len(all_data))]] # snippet 2 data = all_data[(all_data['Source'] == 2 & np.isfinite(all_data[self.design_metric])) | (all_data['Source'] != 2 & np.isfinite(all_data[self.actual_metric]))]
Cada sección (por ejemplo, all_data['Source'] == 2
) hace lo que espero por sí misma, pero parece que estoy haciendo algo mal con los operadores lógicos, ya que el resultado final sale con un resultado diferente a la lista de comprensión. versión.
El operador &
enlaza más fuertemente que ==
(o cualquier operador de comparación). Consulte la documentación . Un ejemplo más simple es:
>>> 2 == 2 & 3 == 3 False
Esto se debe a que se agrupa como 2 == (2 & 3) == 3
, y luego se invoca el encadenamiento de comparación. Esto es lo que está pasando en tu caso. Necesitas poner paréntesis alrededor de cada comparación.
data = all_data[((all_data['Source'] == 2) & np.isfinite(all_data[self.design_metric])) | ((all_data['Source'] != 2) & np.isfinite(all_data[self.actual_metric]))]
Note los paréntesis adicionales alrededor de las comparaciones ==
y !=
.
Junto con la prioridad, hay una diferencia entre los operadores AND y, el primero es booleano y el último binario a nivel binario. Además, debe tener en cuenta las expresiones boolead.
Ver ejemplos en el siguiente fragmento de código:
expresiones lógicas
>>> 1 and 2 1 >>> '1' and '2' '1' >>> 0 == 1 and 2 == 0 or 0 0
operadores bitwise
>>> 1 & 2 0 >>> '1' & '2' Traceback (most recent call last): ... TypeError: unsupported operand type(s) for &: 'str' and 'str' >>> 0 == 1 & 2 == 0 | 0 True