Tengo un DataFrame debajo del cual faltan algunos valores.
df = pd.DataFrame(data=[['A', 1, None], ['B', 2, 5]], columns=['X', 'Y', 'Z']) Dado que se supone que df['Z'] es una columna de enteros, cambié su tipo de datos a pandas nuevo entero anulable de tipo experimental como se muestra a continuación.
ydf['Z'] = ydf['Z'].astype(pd.Int32Dtype()) ydf XYZ 0 A 1 <NA> 1 B 2 5 Ahora estoy tratando de usar un método numpy where simple para reemplazar los valores no nulos en la columna df['Z'] con un valor entero fijo (digamos 1 ) usando el código a continuación.
np.where(pd.isna(ydf['Z']), pd.NA, np.where(ydf['Z'] > 0, 1, 0))Pero recibo el siguiente error y no puedo entender por qué, ya que estoy buscando las filas con valores nulos en la primera condición.
TypeError: boolean value of NA is ambiguousnp.where espera una matriz de valores booleanos. Con el int64 int64, el uso de > en Series devuelve False para nans. Con el dtype Int32 (observe la I mayúscula), > no obliga a nans a False, por lo tanto, el error.
Una solución sería usar ydf['Z'].gt(0).fillna(False) en lugar de ydf['Z'] > 0 . (Son iguales, el segundo solo cambia NA a Falso):
np.where(pd.isna(ydf['Z']), pd.NA, np.where(ydf['Z'].gt(0).fillna(False), 1, 0))Como lo sugirió @ user17242583, np.where necesita una matriz de valores booleanos, pero su comparación devuelve una matriz de tres estados: True , False y <NA> .
>>> df['Z'] > 0 0 <NA> 1 True Name: Z, dtype: boolean En este caso, np.where no puede decidir si el valor devuelto debe interpretarse como True o False .
Simplemente emita sobre la marcha su columna:
>>> np.where(pd.isna(df['Z']), pd.NA, np.where(df['Z'].astype(float) > 0, 1, 0)) array([<NA>, 1], dtype=object)Una opción que podría ser útil aquí es la función case_when de pyjanitor , que podría ayudar con las expresiones anidadas y también funciona con los tipos de matrices de extensión de Pandas:
# pip install pyjanitor import pandas as pd import janitor df.case_when( df.Z.isna(), df.Z, # condition, result df.Z.gt(0), 1, 0, # default value if False column_name='Z') XYZ 0 A 1 <NA> 1 B 2 1