seleccionar - Python pandas aplica función si un valor de columna no es NULL
seleccionar columnas en python (3)
Tengo un marco de datos (en Python 2.7, pandas 0.15.0):
df=
A B C
0 NaN 11 NaN
1 two NaN [''foo'', ''bar'']
2 three 33 NaN
Quiero aplicar una función simple para las filas que no contienen valores NULL en una columna específica. Mi función es lo más sencilla posible:
def my_func(row):
print row
Y mi código de aplicación es el siguiente:
df[[''A'',''B'']].apply(lambda x: my_func(x) if(pd.notnull(x[0])) else x, axis = 1)
Funciona perfectamente. Si quiero verificar la columna ''B'' para valores NULL, el pd.notnull()
funciona perfectamente también. Pero si selecciono la columna ''C'' que contiene objetos de lista:
df[[''A'',''C'']].apply(lambda x: my_func(x) if(pd.notnull(x[1])) else x, axis = 1)
luego me ValueError: (''The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()'', u''occurred at index 1'')
el siguiente mensaje de error: ValueError: (''The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()'', u''occurred at index 1'')
¿Alguien sabe por qué pd.notnull()
funciona solo para columnas de enteros y cadenas, pero no para "columnas de lista"?
Y hay una manera mejor de verificar los valores NULOS en la columna ''C'' en lugar de esto:
df[[''A'',''C'']].apply(lambda x: my_func(x) if(str(x[1]) != ''nan'') else x, axis = 1)
¡Gracias!
El problema es que pd.notnull([''foo'', ''bar''])
opera elementwise y devuelve array([ True, True], dtype=bool)
. Su condición if intenta convertirlo en un valor lógico booleano, y es entonces cuando obtiene la excepción.
Para solucionarlo, simplemente podría envolver la declaración np.all
con np.all
:
df[[''A'',''C'']].apply(lambda x: my_func(x) if(np.all(pd.notnull(x[1]))) else x, axis = 1)
Ahora verás que np.all(pd.notnull([''foo'', ''bar'']))
es realmente True
.
Otra forma es simplemente usar row.notnull().all()
(sin numpy
), aquí hay un ejemplo:
df.apply(lambda row: func1(row) if row.notnull().all() else func2(row), axis=1)
Aquí hay un ejemplo completo en tu df:
>>> d = {''A'': [None, 2, 3, 4], ''B'': [11, None, 33, 4], ''C'': [None, [''a'',''b''], None, 4]}
>>> df = pd.DataFrame(d)
>>> df
A B C
0 NaN 11.0 None
1 2.0 NaN [a, b]
2 3.0 33.0 None
3 4.0 4.0 4
>>> def func1(r):
... return ''No''
...
>>> def func2(r):
... return ''Yes''
...
>>> df.apply(lambda row: func1(row) if row.notnull().all() else func2(row), axis=1)
0 Yes
1 Yes
2 Yes
3 No
Y una captura de pantalla más amigable :-)
Tuve una columna que contenía listas y NaN
s. Entonces, el siguiente funcionó para mí.
df.C.map(lambda x: my_func(x) if type(x) == list else x)