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]}
Prince Bhatti
fonte
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}}
Alex Riley
fonte
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]}

fonte
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]
Farhad Maleki
fonte
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)}
Kamil Sindi
fonte
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

Muhammad Moiz Ahmed
fonte
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},
 ... }
Victoria Stuart
fonte
-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

Umer
fonte
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