Converter dict Python em um dataframe

299

Eu tenho um dicionário Python como o seguinte:

{u'2012-06-08': 388,
 u'2012-06-09': 388,
 u'2012-06-10': 388,
 u'2012-06-11': 389,
 u'2012-06-12': 389,
 u'2012-06-13': 389,
 u'2012-06-14': 389,
 u'2012-06-15': 389,
 u'2012-06-16': 389,
 u'2012-06-17': 389,
 u'2012-06-18': 390,
 u'2012-06-19': 390,
 u'2012-06-20': 390,
 u'2012-06-21': 390,
 u'2012-06-22': 390,
 u'2012-06-23': 390,
 u'2012-06-24': 390,
 u'2012-06-25': 391,
 u'2012-06-26': 391,
 u'2012-06-27': 391,
 u'2012-06-28': 391,
 u'2012-06-29': 391,
 u'2012-06-30': 391,
 u'2012-07-01': 391,
 u'2012-07-02': 392,
 u'2012-07-03': 392,
 u'2012-07-04': 392,
 u'2012-07-05': 392,
 u'2012-07-06': 392}

As chaves são datas Unicode e os valores são números inteiros. Gostaria de converter isso em um dataframe de pandas, tendo as datas e seus valores correspondentes como duas colunas separadas. Exemplo: col1: Datas col2: DateValue (as datas ainda são Unicode e os valores de dados ainda são inteiros)

     Date         DateValue
0    2012-07-01    391
1    2012-07-02    392
2    2012-07-03    392
.    2012-07-04    392
.    ...           ...
.    ...           ...

Qualquer ajuda nessa direção seria muito apreciada. Não consigo encontrar recursos nos documentos do pandas para me ajudar com isso.

Eu sei que uma solução pode ser converter cada par de valor-chave neste ditado, em um ditado, para que toda a estrutura se torne um ditado de ditados e, em seguida, podemos adicionar cada linha individualmente ao quadro de dados. Mas quero saber se existe uma maneira mais fácil e mais direta de fazer isso.

Até agora, tentei converter o dict em um objeto de série, mas isso não parece manter o relacionamento entre as colunas:

s  = Series(my_dict,index=my_dict.keys())
anonuser0428
fonte
Tentei converter o dict em um objeto de série com as datas como índice, mas isso não coincidiu as datas com os valores correspondentes por algum motivo.
Anonuser0428
o código foi publicado. Quero saber se existe uma maneira de criar um quadro de dados sem criar um ditado-de-dict e adicionar cada linha separadamente.
Anonuser0428
1
O que é uma "data Unicode"? Você quer dizer uma data ISO 8601 ?
Peter Mortensen

Respostas:

461

O erro aqui é desde que você chamou o construtor DataFrame com valores escalares (onde espera que os valores sejam uma lista / dict / ... ou seja, tenham várias colunas):

pd.DataFrame(d)
ValueError: If using all scalar values, you must must pass an index

Você pode pegar os itens do dicionário (ou seja, os pares de valores-chave):

In [11]: pd.DataFrame(d.items())  # or list(d.items()) in python 3
Out[11]:
             0    1
0   2012-07-02  392
1   2012-07-06  392
2   2012-06-29  391
3   2012-06-28  391
...

In [12]: pd.DataFrame(d.items(), columns=['Date', 'DateValue'])
Out[12]:
          Date  DateValue
0   2012-07-02        392
1   2012-07-06        392
2   2012-06-29        391

Mas acho que faz mais sentido passar no construtor Series:

In [21]: s = pd.Series(d, name='DateValue')
Out[21]:
2012-06-08    388
2012-06-09    388
2012-06-10    388

In [22]: s.index.name = 'Date'

In [23]: s.reset_index()
Out[23]:
          Date  DateValue
0   2012-06-08        388
1   2012-06-09        388
2   2012-06-10        388
Andy Hayden
fonte
4
@ user1009091 Eu percebi o que o erro significa agora, está basicamente dizendo "O que estou vendo é uma série, então use o construtor Series".
Andy Hayden
1
Obrigado - muito útil. Você poderia explicar qual é a diferença entre usar esse método e usar DataFrame.from_dict ()? Seu método (que eu usei) retorna type = pandas.core.frame.DataFrame, enquanto o outro retorna type = class 'pandas.core.frame.DataFrame'. Alguma chance de você explicar a diferença e quando cada método é apropriado? Agradecemos antecipadamente :)
Optimesh
os dois são semelhantes, from_dicttem um orient kwarg, então eu poderia usá-lo se quisesse evitar a transposição. Existem poucas opções com from_dict, sob o capô, não é realmente diferente do uso do construtor DataFrame.
Andy Hayden
54
Eu estou vendo pandas.core.common.PandasError: DataFrame constructor not properly called!desde o primeiro exemplo
allthesignals
18
@allthesignals adicionando list () em torno de d.items funciona: pd.DataFrame (list (d.items ()), columns = ['Date', 'DateValue'])
sigurdb
142

Ao converter um dicionário em um dataframe do pandas, no qual você deseja que as chaves sejam as colunas do referido dataframe e os valores nos valores da linha, basta colocar colchetes no dicionário da seguinte maneira:

>>> dict_ = {'key 1': 'value 1', 'key 2': 'value 2', 'key 3': 'value 3'}
>>> pd.DataFrame([dict_])

    key 1     key 2     key 3
0   value 1   value 2   value 3

Isso me salvou algumas dores de cabeça, então espero que ajude alguém lá fora!

EDIT: Nos documentos do pandas, uma opção para o dataparâmetro no construtor DataFrame é uma lista de dicionários. Aqui estamos passando uma lista com um dicionário.

cheevahagadog
fonte
6
Sim, eu também fiz isso, mas adicionei .T para transpor.
Anton vBR 14/02
1
Funciona bem, mas não sei por que temos que fazer assim.
hui chen
E se eu quiser um destes coluna para ser usado como índice
om tripathi
102

Conforme explicado em outra resposta, o uso pandas.DataFrame()direto aqui não funcionará como você pensa.

O que você pode fazer é usar pandas.DataFrame.from_dictcom orient='index':

In[7]: pandas.DataFrame.from_dict({u'2012-06-08': 388,
 u'2012-06-09': 388,
 u'2012-06-10': 388,
 u'2012-06-11': 389,
 u'2012-06-12': 389,
 .....
 u'2012-07-05': 392,
 u'2012-07-06': 392}, orient='index', columns=['foo'])
Out[7]: 
            foo
2012-06-08  388
2012-06-09  388
2012-06-10  388
2012-06-11  389
2012-06-12  389
........
2012-07-05  392
2012-07-06  392
ntg
fonte
1
podemos encadear isso com qualquer renamemétodo para também definir os nomes do índice e das colunas de uma só vez?
Ciprian Tomoiagă
4
bom ponto. Um exemplo seria: ...., orient = 'index'). Renomear (colunas = {0: 'foobar'})
ntg
1
Você também pode especificar pandas.DataFrame.from_dict (..., orient = 'index', colunas = ['foo', 'bar']), isto é da fonte listada acima .
spen.smith
bom ponto, isso é verdade de pandas .22, que foi depois da resposta original ... atualizei a minha resposta ...
NTG
69

Passe os itens do dicionário para o construtor DataFrame e forneça os nomes das colunas. Depois disso, analise a Datecoluna para obter Timestampvalores.

Observe a diferença entre python 2.xe 3.x:

No python 2.x:

df = pd.DataFrame(data.items(), columns=['Date', 'DateValue'])
df['Date'] = pd.to_datetime(df['Date'])

No Python 3.x: (exigindo uma 'lista' adicional)

df = pd.DataFrame(list(data.items()), columns=['Date', 'DateValue'])
df['Date'] = pd.to_datetime(df['Date'])
Viktor Kerkez
fonte
3
Isso me dá:PandasError: DataFrame constructor not properly called!
Chris Nielsen
18
@ChrisNielsen Você provavelmente está usando python3. Você deve tentar: #df = pd.DataFrame(list(data.items()), columns=['Date', 'DateValue'])
Viktor Kerkez 22/11
Esta é a melhor resposta, porque mostra o que deve ser feito em Python 3.
ifly6
10

Os pandas possuem função interna para conversão de dict em quadro de dados.

pd.DataFrame.from_dict (dictionaryObject, orient = 'index')

Para seus dados, você pode convertê-lo como abaixo:

import pandas as pd
your_dict={u'2012-06-08': 388,
 u'2012-06-09': 388,
 u'2012-06-10': 388,
 u'2012-06-11': 389,
 u'2012-06-12': 389,
 u'2012-06-13': 389,
 u'2012-06-14': 389,
 u'2012-06-15': 389,
 u'2012-06-16': 389,
 u'2012-06-17': 389,
 u'2012-06-18': 390,
 u'2012-06-19': 390,
 u'2012-06-20': 390,
 u'2012-06-21': 390,
 u'2012-06-22': 390,
 u'2012-06-23': 390,
 u'2012-06-24': 390,
 u'2012-06-25': 391,
 u'2012-06-26': 391,
 u'2012-06-27': 391,
 u'2012-06-28': 391,
 u'2012-06-29': 391,
 u'2012-06-30': 391,
 u'2012-07-01': 391,
 u'2012-07-02': 392,
 u'2012-07-03': 392,
 u'2012-07-04': 392,
 u'2012-07-05': 392,
 u'2012-07-06': 392}

your_df_from_dict=pd.DataFrame.from_dict(your_dict,orient='index')
print(your_df_from_dict)
Suat Atan PhD
fonte
2
Essa é uma solução muito ruim, pois salva as chaves do dicionário como índice.
Economista
6
pd.DataFrame({'date' : dict_dates.keys() , 'date_value' : dict_dates.values() })
Nader Hisham
fonte
5

Você também pode simplesmente passar as chaves e os valores do dicionário para o novo quadro de dados, assim:

import pandas as pd

myDict = {<the_dict_from_your_example>]
df = pd.DataFrame()
df['Date'] = myDict.keys()
df['DateValue'] = myDict.values()
Blairg23
fonte
5

No meu caso, eu queria que as chaves e os valores de um ditado fossem colunas e valores do DataFrame. Então, a única coisa que funcionou para mim foi:

data = {'adjust_power': 'y', 'af_policy_r_submix_prio_adjust': '[null]', 'af_rf_info': '[null]', 'bat_ac': '3500', 'bat_capacity': '75'} 

columns = list(data.keys())
values = list(data.values())
arr_len = len(values)

pd.DataFrame(np.array(values, dtype=object).reshape(1, arr_len), columns=columns)
Artem Zaika
fonte
5

Foi o que funcionou para mim, pois eu queria ter uma coluna de índice separada

df = pd.DataFrame.from_dict(some_dict, orient="index").reset_index()
df.columns = ['A', 'B']
John Doe
fonte
3

Aceita um ditado como argumento e retorna um quadro de dados com as chaves do ditado como índice e os valores como uma coluna.

def dict_to_df(d):
    df=pd.DataFrame(d.items())
    df.set_index(0, inplace=True)
    return df
primeiramente
fonte
ditar, retorna um quadro de dados
primeiro
3

É assim que funcionou para mim:

df= pd.DataFrame([d.keys(), d.values()]).T
df.columns= ['keys', 'values']  # call them whatever you like

Eu espero que isso ajude

Soufiane Chami
fonte
1
d = {'Date': list(yourDict.keys()),'Date_Values': list(yourDict.values())}
df = pandas.DataFrame(data=d)

Se você não encapsular yourDict.keys()dentro de list(), você terminará com todas as suas chaves e valores sendo colocados em todas as linhas de cada coluna. Como isso:

Date \ 0 (2012-06-08, 2012-06-09, 2012-06-10, 2012-06-1...
1 (2012-06-08, 2012-06-09, 2012-06-10, 2012-06-1...
2 (2012-06-08, 2012-06-09, 2012-06-10, 2012-06-1...
3 (2012-06-08, 2012-06-09, 2012-06-10, 2012-06-1...
4 (2012-06-08, 2012-06-09, 2012-06-10, 2012-06-1...

Mas, adicionando list()o resultado, fica assim:

Date Date_Values 0 2012-06-08 388 1 2012-06-09 388 2 2012-06-10 388 3 2012-06-11 389 4 2012-06-12 389 ...

NL23codes
fonte
0

Encontrei isso várias vezes e tenho um exemplo de dicionário que criei a partir de uma função get_max_Path(), e ele retorna o exemplo de dicionário:

{2: 0.3097502930247044, 3: 0.4413177909384636, 4: 0.5197224051562838, 5: 0.5717654946470984, 6: 0.6063959031223476, 7: 0.6365209824708223, 8: 0.655918861281035, 9: 0.680844386645206}

Para converter isso em um quadro de dados, executei o seguinte:

df = pd.DataFrame.from_dict(get_max_path(2), orient = 'index').reset_index()

Retorna um quadro de dados simples de duas colunas com um índice separado:

index 0 0 2 0.309750 1 3 0.441318

Apenas renomeie as colunas usando f.rename(columns={'index': 'Column1', 0: 'Column2'}, inplace=True)

Bryan Butler
fonte
0

Eu acho que você pode fazer algumas alterações no seu formato de dados ao criar um dicionário e convertê-lo facilmente em DataFrame:

entrada:

a={'Dates':['2012-06-08','2012-06-10'],'Date_value':[388,389]}

resultado:

{'Date_value': [388, 389], 'Dates': ['2012-06-08', '2012-06-10']}

entrada:

aframe=DataFrame(a)

output: será seu DataFrame

Você só precisa usar alguma edição de texto em algum lugar como o Sublime ou talvez o Excel.

Arman Nemat Pasand
fonte