Estou tentando reprogramar meu código Stata em Python para melhorias de velocidade, e fui apontado na direção de PANDAS. Estou, no entanto, tendo dificuldade em entender como processar os dados.
Digamos que eu queira iterar todos os valores no cabeçalho da coluna 'ID'. Se esse ID corresponder a um número específico, quero alterar dois valores correspondentes FirstName e LastName.
No Stata, é assim:
replace FirstName = "Matt" if ID==103
replace LastName = "Jones" if ID==103
Portanto, isso substitui todos os valores em FirstName que correspondem aos valores de ID == 103 para Matt.
No PANDAS, estou tentando algo assim
df = read_csv("test.csv")
for i in df['ID']:
if i ==103:
...
Não tenho certeza para onde ir a partir daqui. Alguma ideia?
df.loc[df.ID == 103, ['FirstName', 'LastName']] = 'Matt', 'Jones'
Você pode usar
map
, ele pode mapear valores de um dicionário ou até mesmo uma função personalizada.Suponha que este seja o seu df:
Crie os dictos:
E mapa:
O resultado será:
Ou use uma função personalizada:
fonte
dict
é criado para o mapeamento. Caso contrário, alguma verificação / limpeza pode ser feita com base em algo como:df.ID.isin(names.keys())
A pergunta original trata de um caso de uso específico e restrito. Para aqueles que precisam de respostas mais genéricas, aqui estão alguns exemplos:
Criação de uma nova coluna usando dados de outras colunas
Dado o quadro de dados abaixo:
Abaixo, estamos adicionando uma nova
description
coluna como uma concatenação de outras colunas usando a+
operação que é substituída por séries. Formatação de string extravagante, strings f etc. não funcionarão aqui, pois+
se aplica a valores escalares e não a valores 'primitivos':Obtemos
1 years
o gato (em vez de1 year
), que corrigiremos a seguir usando condicionais.Modificando uma coluna existente com condicionais
Aqui, estamos substituindo a
animal
coluna original por valores de outras colunas e usandonp.where
para definir uma substring condicional com base no valor deage
:Modificando várias colunas com condicionais
Uma abordagem mais flexível é chamar
.apply()
um dataframe inteiro em vez de uma única coluna:No código acima, a
transform_row(r)
função pega umSeries
objeto que representa uma determinada linha (indicado poraxis=1
, o valor padrão deaxis=0
fornecerá umSeries
objeto para cada coluna). Isso simplifica o processamento, pois podemos acessar os valores 'primitivos' reais na linha usando os nomes das colunas e ter visibilidade de outras células na linha / coluna fornecida.fonte
np.where
é provavelmente o que você está procurando, consulte, por exemplo, stackoverflow.com/a/42540310/191246, mas também é possível que você não consiga ajustar a lógica em uma operação escalar, então você precisa transformar explicitamente a célula numericamente semelhante a como é feita emtransform_row
Essa pergunta ainda pode ser consultada com frequência suficiente para que valha a pena oferecer um adendo à resposta do Sr. Kassies. A
dict
classe interna pode ser subclassificada de forma que um padrão seja retornado para as chaves 'ausentes'. Este mecanismo funciona bem para pandas. Mas veja abaixo.Desta forma, é possível evitar erros de chave.
A mesma coisa pode ser feita de maneira mais simples da seguinte maneira. O uso do argumento 'default' para o
get
método de um objeto dict torna desnecessário criar uma subclasse de um dict.fonte