Adicionar coluna no dataframe da lista


98

Eu tenho um dataframe com algumas colunas como esta:

A   B   C  
0   
4
5
6
7
7
6
5

O intervalo possível de valores em A é apenas de 0 a 7 .

Além disso, tenho uma lista de 8 elementos como esta:

List=[2,5,6,8,12,16,26,32]  //There are only 8 elements in this list

Se o elemento na coluna A é n , eu preciso inserir o n º elemento da lista em uma nova coluna, digamos, 'D'.

Como posso fazer isso de uma vez sem fazer um loop em todo o dataframe?

O dataframe resultante ficaria assim:

A   B   C   D
0           2
4           12
5           16
6           26
7           32
7           32
6           26
5           16

Observação: o dataframe é enorme e a iteração é a última opção. Mas também posso organizar os elementos em 'List' em qualquer outra estrutura de dados como dict, se necessário.


1
Acho que você precisa de um exemplo de brinquedo (menor), com o resultado desejado. Parece um pouco vago atm.
— Andy Hayden,

11
Nunca, jamais chame uma variável de "Lista". Em qualquer idioma.
— lucid_dreamer

Respostas:


51

IIUC, se você transformar seu (infelizmente chamado) Listem um ndarray, você pode simplesmente indexar nele naturalmente.

>>> import numpy as np
>>> m = np.arange(16)*10
>>> m[df.A]
array([  0,  40,  50,  60, 150, 150, 140, 130])
>>> df["D"] = m[df.A]
>>> df
    A   B   C    D
0   0 NaN NaN    0
1   4 NaN NaN   40
2   5 NaN NaN   50
3   6 NaN NaN   60
4  15 NaN NaN  150
5  15 NaN NaN  150
6  14 NaN NaN  140
7  13 NaN NaN  130

Aqui eu construí um novo m, mas se você usar m = np.asarray(List), a mesma coisa deve funcionar: os valores em df.Aescolherão os elementos apropriados de m.


Observe que se você estiver usando uma versão antiga do numpy, talvez precise usar m[df.A.values]em seu lugar - no passado, numpynão funcionava bem com os outros, e alguma refatoração pandascausava algumas dores de cabeça. As coisas melhoraram agora.


Olá @DSM. Eu entendi o que você está dizendo, mas estou recebendo este erro: Traceback (most recent call last): File "./b.py", line 24, in <module> d["D"] = m[d.A] IndexError: unsupported iterator index
— mane

1
@mane: urf, esse é um numpybug antigo . Funciona d["D"] = m[d.A.values]para você?
— DSM

283

Basta atribuir a lista diretamente:

df['new_col'] = mylist

Alternativa
Converta a lista em uma série ou matriz e atribua:

se = pd.Series(mylist)
df['new_col'] = se.values

ou

df['new_col'] = np.array(mylist)

3
pykernel_launcher.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy """Entry point for launching an IPython kernel.
— Ilya Rusin

@sparrow vai usar o pd.Seriesefeito do dtype? Quero dizer, isso deixará flutuadores como flutuadores e strings como strings? Ou os elementos da lista serão padronizados para strings?
— 3kstc

2
@IlyaRusin, é um falso positivo que pode ser ignorado neste caso. Para mais informações: stackoverflow.com/questions/20625582/…
— sparrow

1
Isso pode ser simplificado para: df ['new_col'] = pd.Series (mylist) .values
— smartse

17

Uma solução aprimorada no grande do @sparrow.

Deixe df , ser seu conjunto de dados, e mylist a lista com os valores que você deseja adicionar ao dataframe.

Suponhamos que você queira chamar sua nova coluna simplesmente, new_column

Primeiro faça a lista em uma série:

column_values = pd.Series(mylist)

Em seguida, use a função de inserção para adicionar a coluna. Esta função tem a vantagem de permitir que você escolha em que posição deseja colocar a coluna. No exemplo a seguir, posicionaremos a nova coluna na primeira posição a partir da esquerda (definindo loc = 0)

df.insert(loc=0, column='new_column', value=column_values)

Isso não funcionará se você alterar seus índices de df para algo diferente de 1,2,3 ... nesse caso, você tem que adicionar entre as linhas: column_values.index = df.index
— Guy's

8

Primeiro, vamos criar o dataframe que você tinha. Vou ignorar as colunas B e C porque não são relevantes.

df = pd.DataFrame({'A': [0, 4, 5, 6, 7, 7, 6,5]})

E o mapeamento que você deseja:

mapping = dict(enumerate([2,5,6,8,12,16,26,32]))

df['D'] = df['A'].map(mapping)

Feito!

print df

Resultado:

   A   D
0  0   2
1  4  12
2  5  16
3  6  26
4  7  32
5  7  32
6  6  26
7  5  16

1
Acho que o OP já sabe fazer isso. Pela minha leitura, o problema está sendo construído a Dpartir dos elementos de Ae List("Se o elemento na coluna A for n, preciso inserir o enésimo elemento da lista em uma nova coluna, diga 'D'.")
— DSM

SO se transformou em algum tipo de F (* & nanny state. Obrigado a @DSM pelo comentário, mas não consegui corrigir a postagem até que fosse revisada por pares. E então foi rejeitada porque era muito rápida. E então eu fui capaz de revisar minha própria edição. e então é tarde demais porque uma resposta pior (IMHO) foi "aceita". ASSIM, realmente tenho algumas metannys que são menos do que úteis !!!!
— Phil Cooper

Bem, não posso falar pelas babás, mas você descobrirá que sua abordagem é uma ordem de magnitude mais lenta em matrizes longas. Em outros aspectos, é claro, escolher entre np.array(List)[df.A]e df["A"].map(dict(enumerate(List)))é principalmente uma questão de preferência.
— DSM

Olá, Phil, Só vi sua solução e o comentário do DSM e nunca mais voltei, pois a solução do DSM funcionou bem para mim. Mas agora, olhando para sua solução, ela também funciona. Eu executei a solução do DSM em meu conjunto de dados de cerca de 200 mil entradas e ele é executado em alguns segundos com todos os outros cálculos que tenho. Eu sou totalmente novo em python-pandas e pessoalmente não estava procurando por nada elegante ou ótimo; tudo o que funcionou estava bem. Mas, honestamente, obrigado pela solução.
— mane

2

Velha pergunta; mas eu sempre tento usar o código mais rápido!

Eu tinha uma lista enorme com 69 milhões de uint64. np.array () foi o mais rápido para mim.

df['hashes'] = hashes
Time spent: 17.034842014312744

df['hashes'] = pd.Series(hashes).values
Time spent: 17.141014337539673

df['key'] = np.array(hashes)
Time spent: 10.724546194076538
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.