Tengo un DataFrame df
:
A B
a 2 2
b 3 1
c 1 3
Quiero crear una nueva columna según los siguientes criterios:
si fila A == B: 0
si filaA > B: 1
si fila A < B: -1
así que dada la tabla anterior, debería ser:
A B C
a 2 2 0
b 3 1 1
c 1 3 -1
Para los if else
casos típicos que hago np.where(df.A > df.B, 1, -1)
, ¿los pandas proporcionan una sintaxis especial para resolver mi problema con un paso (sin la necesidad de crear 3 columnas nuevas y luego combinar el resultado)?
python
pandas
conditional
loco
fuente
fuente
apply
y estableceraxis=1
funcionaría, no estoy seguro de poder pensar en una operación que le dé lo que deseadf['C']=df.apply(myFunc(row), axis=1)
donde myFunc hace lo que quieres, esto no implica la creación de '3 columnas'Respuestas:
Para formalizar algunos de los enfoques expuestos anteriormente:
Cree una función que opere en las filas de su marco de datos así:
def f(row): if row['A'] == row['B']: val = 0 elif row['A'] > row['B']: val = 1 else: val = -1 return val
Luego, aplíquelo a su marco de datos pasando la
axis=1
opción:In [1]: df['C'] = df.apply(f, axis=1) In [2]: df Out[2]: A B C a 2 2 0 b 3 1 1 c 1 3 -1
Por supuesto, esto no está vectorizado, por lo que el rendimiento puede no ser tan bueno cuando se escala a una gran cantidad de registros. Aún así, creo que es mucho más legible. Especialmente viniendo de un fondo SAS.
Editar
Aquí está la versión vectorizada
df['C'] = np.where( df['A'] == df['B'], 0, np.where( df['A'] > df['B'], 1, -1))
fuente
args
parámetro de la.apply
función: pandas.pydata.org/pandas-docs/stable/generated/…data df; set df; if A=B then C=0; else if A>B then C=1; else C=-1; run;
Muy elegante y simple.df.loc[df['A'] == df['B'], 'C'] = 0 df.loc[df['A'] > df['B'], 'C'] = 1 df.loc[df['A'] < df['B'], 'C'] = -1
Fácil de resolver mediante indexación. La primera línea de código se lee así, si la columna
A
es igual a la columnaB
, cree y establezca la columnaC
igual a 0.fuente
Para esta relación en particular, puede utilizar
np.sign
:>>> df["C"] = np.sign(df.A - df.B) >>> df A B C a 2 2 0 b 3 1 1 c 1 3 -1
fuente
Digamos que el anterior es su marco de datos original y desea agregar una nueva columna 'antigua'
Si la edad es mayor de 50 años, la consideramos mayor = sí en caso contrario Falso
paso 1: obtener los índices de las filas cuya antigüedad sea mayor a 50
row_indexes=df[df['age']>=50].index
paso 2: usando .loc podemos asignar un nuevo valor a la columna
df.loc[row_indexes,'elderly']="yes"
lo mismo para la edad menor de 50
row_indexes=df[df['age']<50].index
df[row_indexes,'elderly']="no"
fuente