Eu tenho um DataFrame df
:
A B
a 2 2
b 3 1
c 1 3
Quero criar uma nova coluna com base nos seguintes critérios:
se linha A == B: 0
se linhaA > B: 1
se linha A < B: -1
então, dada a tabela acima, deveria ser:
A B C
a 2 2 0
b 3 1 1
c 1 3 -1
Para if else
casos típicos que eu faço np.where(df.A > df.B, 1, -1)
, o pandas fornece uma sintaxe especial para resolver meu problema com uma etapa (sem a necessidade de criar 3 novas colunas e, em seguida, combinar o resultado)?
python
pandas
conditional
nozes
fonte
fonte
apply
e definiraxis=1
funcionaria, não tenho certeza se posso pensar em uma operação que daria a você o que você desejadf['C']=df.apply(myFunc(row), axis=1)
onde myFunc faz o que você quer, isso não envolve a criação de '3 colunas'Respostas:
Para formalizar algumas das abordagens apresentadas acima:
Crie uma função que opere nas linhas de seu dataframe assim:
def f(row): if row['A'] == row['B']: val = 0 elif row['A'] > row['B']: val = 1 else: val = -1 return val
Em seguida, aplique-o ao seu dataframe passando a
axis=1
opção: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
Obviamente, isso não é vetorizado, portanto o desempenho pode não ser tão bom quando dimensionado para um grande número de registros. Ainda assim, acho que é muito mais legível. Especialmente vindo de um histórico SAS.
Editar
Aqui está a versão vetorial
df['C'] = np.where( df['A'] == df['B'], 0, np.where( df['A'] > df['B'], 1, -1))
fonte
args
parâmetro da.apply
função: 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;
Muito elegante e simples.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 usando indexação. A primeira linha do código é assim: se coluna
A
for igual a colunaB
, crie e defina colunaC
igual a 0.fonte
Para este relacionamento específico, você pode usar
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
fonte
Digamos que um é o seu quadro de dados original e você deseja adicionar uma nova coluna 'antiga'
Se a idade for maior que 50, então consideramos como mais velho = sim, caso contrário, False
etapa 1: obter os índices de linhas com idade superior a 50
row_indexes=df[df['age']>=50].index
etapa 2: usando .loc, podemos atribuir um novo valor à coluna
df.loc[row_indexes,'elderly']="yes"
mesmo para idade abaixo de 50
row_indexes=df[df['age']<50].index
df[row_indexes,'elderly']="no"
fonte
Quando você tem várias
if
condições,numpy.select
é o caminho a seguir:In [4102]: import numpy as np In [4098]: conditions = [df.A.eq(df.B), df.A.gt(df.B), df.A.lt(df.B)] In [4096]: choices = [0, 1, -1] In [4100]: df['C'] = np.select(conditions, choices) In [4101]: df Out[4101]: A B C a 2 2 0 b 3 1 1 c 1 3 -1
fonte