Converter um DataFrame do Pandas em um dicionário


168

Eu tenho um DataFrame com quatro colunas. Quero converter esse DataFrame em um dicionário python. Quero que os elementos da primeira coluna sejam keyse os elementos de outras colunas na mesma linha values.

Quadro de dados:

    ID   A   B   C
0   p    1   3   2
1   q    4   3   2
2   r    4   0   9  

A saída deve ser assim:

Dicionário:

{'p': [1,3,2], 'q': [4,3,2], 'r': [4,0,9]}

4
Dataframe.to_dict()?
Anzel

3
Dataframe.to_dict()fará A,B,Cas chaves em vez dep,q,r
Prince Bhatti

@jezrael como obter a seguinte saída? {2: {'p': [1,3]}, 2: {'q': [4,3]}, 9: {'r': [4,0]}} para o mesmo conjunto de dados?
Panda

equivalentes da coluna @jezrael da pergunta acima {'c': {'ID': 'A', 'B'}}
panda

Respostas:


338

O to_dict()método define os nomes das colunas como chaves de dicionário, para que você precise remodelar um pouco o DataFrame. Definir a coluna 'ID' como o índice e depois transpor o DataFrame é uma maneira de conseguir isso.

to_dict()também aceita um argumento 'orientar', necessário para gerar uma lista de valores para cada coluna. Caso contrário, um dicionário do formulário {index: value}será retornado para cada coluna.

Essas etapas podem ser executadas com a seguinte linha:

>>> df.set_index('ID').T.to_dict('list')
{'p': [1, 3, 2], 'q': [4, 3, 2], 'r': [4, 0, 9]}

Caso seja necessário um formato de dicionário diferente, aqui estão exemplos dos possíveis argumentos orientais. Considere o seguinte DataFrame simples:

>>> df = pd.DataFrame({'a': ['red', 'yellow', 'blue'], 'b': [0.5, 0.25, 0.125]})
>>> df
        a      b
0     red  0.500
1  yellow  0.250
2    blue  0.125

Então as opções são as seguintes.

dict - o padrão: nomes de colunas são chaves, valores são dicionários de índice: pares de dados

>>> df.to_dict('dict')
{'a': {0: 'red', 1: 'yellow', 2: 'blue'}, 
 'b': {0: 0.5, 1: 0.25, 2: 0.125}}

list - chaves são nomes de colunas, valores são listas de dados da coluna

>>> df.to_dict('list')
{'a': ['red', 'yellow', 'blue'], 
 'b': [0.5, 0.25, 0.125]}

series - como 'list', mas os valores são Series

>>> df.to_dict('series')
{'a': 0       red
      1    yellow
      2      blue
      Name: a, dtype: object, 

 'b': 0    0.500
      1    0.250
      2    0.125
      Name: b, dtype: float64}

split - divide colunas / dados / índice como chaves, com valores sendo nomes de colunas, valores de dados por linha e rótulos de índice, respectivamente

>>> df.to_dict('split')
{'columns': ['a', 'b'],
 'data': [['red', 0.5], ['yellow', 0.25], ['blue', 0.125]],
 'index': [0, 1, 2]}

registros - cada linha se torna um dicionário em que chave é o nome da coluna e valor é os dados na célula

>>> df.to_dict('records')
[{'a': 'red', 'b': 0.5}, 
 {'a': 'yellow', 'b': 0.25}, 
 {'a': 'blue', 'b': 0.125}]

índice - como 'registros', mas um dicionário de dicionários com chaves como rótulos de índice (em vez de uma lista)

>>> df.to_dict('index')
{0: {'a': 'red', 'b': 0.5},
 1: {'a': 'yellow', 'b': 0.25},
 2: {'a': 'blue', 'b': 0.125}}

14
este será um liner:df.set_index('ID').T.to_dict('list')
Anzel 3/14

1
Para um registro no quadro de dados. df.T.to_dict () [0]
kamran kausar

23

Tente usar Zip

df = pd.read_csv("file")
d= dict([(i,[a,b,c ]) for i, a,b,c in zip(df.ID, df.A,df.B,df.C)])
print d

Resultado:

{'p': [1, 3, 2], 'q': [4, 3, 2], 'r': [4, 0, 9]}

21

Siga esses passos:

Suponha que seu quadro de dados seja o seguinte:

>>> df
   A  B  C ID
0  1  3  2  p
1  4  3  2  q
2  4  0  9  r

1. Use set_indexpara definir IDcolunas como o índice do quadro de dados.

    df.set_index("ID", drop=True, inplace=True)

2. Use o orient=indexparâmetro para ter o índice como chaves do dicionário.

    dictionary = df.to_dict(orient="index")

Os resultados serão os seguintes:

    >>> dictionary
    {'q': {'A': 4, 'B': 3, 'D': 2}, 'p': {'A': 1, 'B': 3, 'D': 2}, 'r': {'A': 4, 'B': 0, 'D': 9}}

3. Se você precisar ter cada amostra como uma lista, execute o código a seguir. Determinar a ordem das colunas

column_order= ["A", "B", "C"] #  Determine your preferred order of columns
d = {} #  Initialize the new dictionary as an empty dictionary
for k in dictionary:
    d[k] = [dictionary[k][column_name] for column_name in column_order]

2
Para o último bit, parece que você seria mais simples usando uma compreensão de ditado para substituir a compreensão de loop for + list (3 linhas -> 1). De qualquer forma, embora seja bom ter opções, a resposta principal é muito mais curta.
fantabolous

Isso é útil porque explica claramente como usar uma coluna ou cabeçalho específico como o índice.
Tropicalrambler

10

Se você não se importa que os valores do dicionário sejam tuplas, use ituplos:

>>> {x[0]: x[1:] for x in df.itertuples(index=False)}
{'p': (1, 3, 2), 'q': (4, 3, 2), 'r': (4, 0, 9)}

7

um dicionário como:

{'red': '0.500', 'yellow': '0.250, 'blue': '0.125'}

ser necessário em um quadro de dados como:

        a      b
0     red  0.500
1  yellow  0.250
2    blue  0.125

maneira mais simples seria fazer:

dict(df.values.tolist())

snippet de trabalho abaixo:

import pandas as pd
df = pd.DataFrame({'a': ['red', 'yellow', 'blue'], 'b': [0.5, 0.25, 0.125]})
dict(df.values.tolist())

insira a descrição da imagem aqui


2

Para meu uso (nomes de nós com posições xy), achei a resposta do @ user4179775 para a mais útil / intuitiva:

import pandas as pd

df = pd.read_csv('glycolysis_nodes_xy.tsv', sep='\t')

df.head()
    nodes    x    y
0  c00033  146  958
1  c00031  601  195
...

xy_dict_list=dict([(i,[a,b]) for i, a,b in zip(df.nodes, df.x,df.y)])

xy_dict_list
{'c00022': [483, 868],
 'c00024': [146, 868],
 ... }

xy_dict_tuples=dict([(i,(a,b)) for i, a,b in zip(df.nodes, df.x,df.y)])

xy_dict_tuples
{'c00022': (483, 868),
 'c00024': (146, 868),
 ... }

Termo aditivo

Mais tarde, voltei a esse problema para outro trabalho, mas relacionado. Aqui está uma abordagem que reflete mais de perto a [excelente] resposta aceita.

node_df = pd.read_csv('node_prop-glycolysis_tca-from_pg.tsv', sep='\t')

node_df.head()
   node  kegg_id kegg_cid            name  wt  vis
0  22    22       c00022   pyruvate        1   1
1  24    24       c00024   acetyl-CoA      1   1
...

Converta o quadro de dados do Pandas em [lista], {dict}, {dict of {dict}}, ...

Por resposta aceita:

node_df.set_index('kegg_cid').T.to_dict('list')

{'c00022': [22, 22, 'pyruvate', 1, 1],
 'c00024': [24, 24, 'acetyl-CoA', 1, 1],
 ... }

node_df.set_index('kegg_cid').T.to_dict('dict')

{'c00022': {'kegg_id': 22, 'name': 'pyruvate', 'node': 22, 'vis': 1, 'wt': 1},
 'c00024': {'kegg_id': 24, 'name': 'acetyl-CoA', 'node': 24, 'vis': 1, 'wt': 1},
 ... }

No meu caso, eu queria fazer a mesma coisa, mas com colunas selecionadas no quadro de dados do Pandas, então precisava dividir as colunas. Existem duas abordagens.

  1. Diretamente:

(consulte: Converter pandas em dicionário, definindo as colunas usadas nos valores-chave )

node_df.set_index('kegg_cid')[['name', 'wt', 'vis']].T.to_dict('dict')

{'c00022': {'name': 'pyruvate', 'vis': 1, 'wt': 1},
 'c00024': {'name': 'acetyl-CoA', 'vis': 1, 'wt': 1},
 ... }
  1. "Indiretamente:" primeiro, corte as colunas / dados desejados do quadro de dados do Pandas (novamente, duas abordagens),
node_df_sliced = node_df[['kegg_cid', 'name', 'wt', 'vis']]

ou

node_df_sliced2 = node_df.loc[:, ['kegg_cid', 'name', 'wt', 'vis']]

que pode ser usado para criar um dicionário de dicionários

node_df_sliced.set_index('kegg_cid').T.to_dict('dict')

{'c00022': {'name': 'pyruvate', 'vis': 1, 'wt': 1},
 'c00024': {'name': 'acetyl-CoA', 'vis': 1, 'wt': 1},
 ... }

-1

DataFrame.to_dict() converte o DataFrame em dicionário.

Exemplo

>>> df = pd.DataFrame(
    {'col1': [1, 2], 'col2': [0.5, 0.75]}, index=['a', 'b'])
>>> df
   col1  col2
a     1   0.1
b     2   0.2
>>> df.to_dict()
{'col1': {'a': 1, 'b': 2}, 'col2': {'a': 0.5, 'b': 0.75}}

Consulte esta documentação para obter detalhes


2
Sim, mas o OP explicitamente declarou que deseja que os índices de linha sejam as chaves, não os rótulos da coluna.
Vicki B
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.