Se você tiver apenas duas opções para escolher:
df['color'] = np.where(df['Set']=='Z', 'green', 'red')
Por exemplo,
import pandas as pd
import numpy as np
df = pd.DataFrame({'Type':list('ABBC'), 'Set':list('ZZXY')})
df['color'] = np.where(df['Set']=='Z', 'green', 'red')
print(df)
rendimentos
Set Type color
0 Z A green
1 Z B green
2 X B red
3 Y C red
Se você tiver mais de duas condições, usenp.select
. Por exemplo, se você quiser color
ser
yellow
quando (df['Set'] == 'Z') & (df['Type'] == 'A')
- caso contrário,
blue
quando(df['Set'] == 'Z') & (df['Type'] == 'B')
- caso contrário,
purple
quando(df['Type'] == 'B')
- caso contrário
black
,
então use
df = pd.DataFrame({'Type':list('ABBC'), 'Set':list('ZZXY')})
conditions = [
(df['Set'] == 'Z') & (df['Type'] == 'A'),
(df['Set'] == 'Z') & (df['Type'] == 'B'),
(df['Type'] == 'B')]
choices = ['yellow', 'blue', 'purple']
df['color'] = np.select(conditions, choices, default='black')
print(df)
que produz
Set Type color
0 Z A yellow
1 Z B blue
2 X B purple
3 Y C black
df['foo'] = np.where(df['Set']=='Z', df['Set'], df['Type'].shift(1))
A compreensão da lista é outra maneira de criar outra coluna condicionalmente. Se você estiver trabalhando com tipos de objeto em colunas, como no seu exemplo, as compreensões de lista geralmente superam a maioria dos outros métodos.
Exemplo de compreensão da lista:
% timeit testes:
fonte
pd.DataFrame({'Type':list('ABBC')*100000, 'Set':list('ZZXY')*100000})
tamanho de pensamento ),numpy.where
ultrapassamap
, mas a compreensão da lista é excelente (cerca de 50% mais rápida quenumpy.where
).df['color'] = ['red' if (x['Set'] == 'Z') & (x['Type'] == 'B') else 'green' for x in df]
df['color_type'] = np.where(df['Set']=='Z', 'green', df['Type'])
.iterrows()
é notoriamente lento e o DataFrame não deve ser modificado durante a iteração.Outra maneira pela qual isso pode ser alcançado é
fonte
Aqui está mais uma maneira de esfolar esse gato, usando um dicionário para mapear novos valores nas chaves da lista:
Como é:
Essa abordagem pode ser muito poderosa quando você tem muitas
ifelse
instruções de tipo a fazer (ou seja, muitos valores exclusivos a serem substituídos).E é claro que você sempre pode fazer isso:
Mas essa abordagem é mais do que três vezes mais lenta que a
apply
abordagem de cima, na minha máquina.E você também pode fazer isso usando
dict.get
:fonte
.map()
solução é ~ 10 vezes mais rápida que.apply()
..apply()
leva 47 segundos, contra apenas 5,91 segundos.map()
.A seguir, é mais lento que as abordagens cronometradas aqui , mas podemos calcular a coluna extra com base no conteúdo de mais de uma coluna e mais de dois valores podem ser calculados para a coluna extra.
Exemplo simples usando apenas a coluna "Set":
Exemplo com mais cores e mais colunas consideradas:
Editar (21/06/2019): Usando plydata
Também é possível usar plydata para fazer esse tipo de coisa (isso parece ainda mais lento do que usar
assign
eapply
, no entanto).Simples
if_else
:Aninhado
if_else
:fonte
Talvez isso tenha sido possível com as atualizações mais recentes do Pandas, mas acho que a seguinte é a resposta mais curta e talvez a melhor para a pergunta, até agora. Você pode usar o
.loc
método e usar uma condição ou várias, dependendo da sua necessidade.Resumo do código:
Explicação:
adicione uma coluna 'cor' e defina todos os valores para "vermelho"
Aplique sua única condição:
ou várias condições, se você desejar:
Você pode ler sobre operadores lógicos do Pandas e seleção condicional aqui: Operadores lógicos para indexação booleana no Pandas
fonte
df.loc[(df['Set']=="Z") & (df['Type']=="A"), 'Color'] = "green"
Um revestimento com o
.apply()
método é o seguinte:Depois disso, o
df
quadro de dados fica assim:fonte
Se você estiver trabalhando com dados massivos, uma abordagem memorizada seria melhor:
Essa abordagem será mais rápida quando você tiver muitos valores repetidos. Minha regra geral é memorizar quando:
data_size
>10**4
&n_distinct
<data_size/4
Ex Memoize em um caso de 10.000 linhas com 2.500 ou menos valores distintos.
fonte
random.choices()
.