python - nueva - insertar columna en data frame r
Usar condicional para generar una nueva columna en el marco de datos de pandas (5)
Tengo un marco de datos de pandas que se ve así:
portion used
0 1 1.0
1 2 0.3
2 3 0.0
3 4 0.8
Me gustaría crear una nueva columna basada en la columna
used
, para que el
df
vea así:
portion used alert
0 1 1.0 Full
1 2 0.3 Partial
2 3 0.0 Empty
3 4 0.8 Partial
-
Crear una nueva columna de
alert
basada en -
Si se
used
es1.0
, laalert
debe estarFull
. -
Si se
used
es0.0
, laalert
debe estarEmpty
. -
De lo contrario, la
alert
debe serPartial
.
¿Cuál es la mejor manera de hacer eso?
Alternativamente, podrías hacer:
import pandas as pd
import numpy as np
df = pd.DataFrame(data={''portion'':np.arange(10000), ''used'':np.random.rand(10000)})
%%timeit
df.loc[df[''used''] == 1.0, ''alert''] = ''Full''
df.loc[df[''used''] == 0.0, ''alert''] = ''Empty''
df.loc[(df[''used''] >0.0) & (df[''used''] < 1.0), ''alert''] = ''Partial''
Lo que da el mismo resultado pero se ejecuta aproximadamente 100 veces más rápido en 10000 filas:
100 loops, best of 3: 2.91 ms per loop
Luego usando apply:
%timeit df[''alert''] = df.apply(alert, axis=1)
1 loops, best of 3: 287 ms per loop
Supongo que la elección depende de qué tan grande sea su marco de datos.
No puedo comentar así que hacer una nueva respuesta: Mejorando el enfoque de Ffisegydd, puede usar un diccionario y el método
dict.get()
para hacer que la función que se
.apply()
a
.apply()
sea más fácil de administrar:
import pandas as pd
def alert(c):
mapping = {1.0: ''Full'', 0.0: ''Empty''}
return mapping.get(c[''used''], ''Partial'')
df = pd.DataFrame(data={''portion'':[1, 2, 3, 4], ''used'':[1.0, 0.3, 0.0, 0.8]})
df[''alert''] = df.apply(alert, axis=1)
Dependiendo del caso de uso, es posible que también desee definir el dict fuera de la definición de la función.
Puede definir una función que devuelva sus diferentes estados "Completo", "Parcial", "Vacío", etc. y luego usar
df.apply
para aplicar la función a cada fila.
Tenga en cuenta que debe pasar el argumento de palabra clave
axis=1
para asegurarse de que aplica la función a las filas.
import pandas as pd
def alert(c):
if c[''used''] == 1.0:
return ''Full''
elif c[''used''] == 0.0:
return ''Empty''
elif 0.0 < c[''used''] < 1.0:
return ''Partial''
else:
return ''Undefined''
df = pd.DataFrame(data={''portion'':[1, 2, 3, 4], ''used'':[1.0, 0.3, 0.0, 0.8]})
df[''alert''] = df.apply(alert, axis=1)
# portion used alert
# 0 1 1.0 Full
# 1 2 0.3 Partial
# 2 3 0.0 Empty
# 3 4 0.8 Partial
Use
np.where
, generalmente es rápido
In [845]: df[''alert''] = np.where(df.used == 1, ''Full'',
np.where(df.used == 0, ''Empty'', ''Partial''))
In [846]: df
Out[846]:
portion used alert
0 1 1.0 Full
1 2 0.3 Partial
2 3 0.0 Empty
3 4 0.8 Partial
Tiempos
In [848]: df.shape
Out[848]: (100000, 3)
In [849]: %timeit df[''alert''] = np.where(df.used == 1, ''Full'', np.where(df.used == 0, ''Empty'', ''Partial''))
100 loops, best of 3: 6.17 ms per loop
In [850]: %%timeit
...: df.loc[df[''used''] == 1.0, ''alert''] = ''Full''
...: df.loc[df[''used''] == 0.0, ''alert''] = ''Empty''
...: df.loc[(df[''used''] >0.0) & (df[''used''] < 1.0), ''alert''] = ''Partial''
...:
10 loops, best of 3: 21.9 ms per loop
In [851]: %timeit df[''alert''] = df.apply(alert, axis=1)
1 loop, best of 3: 2.79 s per loop
df[''TaxStatus''] = np.where(df.Public == 1, True, np.where(df.Public == 2, False))
Parece que esto funciona, excepto por ValueError: se debe dar ambos o ninguno de x e y