Konwertuj dict Pythona na ramkę danych


299

Mam słownik Python, taki jak poniżej:

{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}

Kluczami są daty Unicode, a wartościami są liczby całkowite. Chciałbym przekonwertować to na ramkę danych pandy, mając daty i odpowiadające im wartości jako dwie osobne kolumny. Przykład: col1: Daty col2: DateValue (daty są nadal Unicode, a wartości wartości wciąż są liczbami całkowitymi)

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

Każda pomoc w tym kierunku byłaby mile widziana. Nie mogę znaleźć zasobów w dokumentach pand, aby mi w tym pomóc.

Wiem, że jednym rozwiązaniem może być konwersja każdej pary klucz-wartość w tym dykcie, w dykt, aby cała struktura stała się dyktą dykt, a następnie możemy dodać każdy wiersz osobno do ramki danych. Ale chcę wiedzieć, czy istnieje łatwiejszy i bardziej bezpośredni sposób.

Do tej pory próbowałem przekształcić dict w obiekt szeregowy, ale wydaje się, że to nie utrzymuje relacji między kolumnami:

s  = Series(my_dict,index=my_dict.keys())

Próbowałem przekonwertować dict na obiekt szeregowy z datami jako indeksem, ale z jakiegoś powodu nie zgadzało się to z odpowiadającymi im wartościami.
anonuser0428,

kod został opublikowany. Chcę zapytać, czy istnieje sposób na utworzenie ramki danych bez tworzenia dykta, a następnie dodawania każdego wiersza osobno.
anonuser0428

1
Co to jest „data Unicode”? Masz na myśli datę ISO 8601 ?
Peter Mortensen

Odpowiedzi:


461

Błąd polega na tym, że wywołanie konstruktora DataFrame z wartościami skalarnymi (gdzie oczekuje się, że wartości będą listą / dict / ... tj. Będą miały wiele kolumn):

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

Możesz pobrać elementy ze słownika (tj. Pary klucz-wartość):

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

Ale myślę, że bardziej sensowne jest przekazanie konstruktora 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

4
@ user1009091 Zdałem sobie sprawę, co oznacza teraz błąd, w zasadzie mówi „To, co widzę, to seria, więc użyj konstruktora serii”.
Andy Hayden,

1
Dzięki - bardzo pomocny. Czy mógłbyś wyjaśnić, jaka jest różnica między użyciem tej metody a użyciem DataFrame.from_dict ()? Twoja metoda (której użyłem) zwraca typ = pandas.core.frame.DataFrame, podczas gdy druga zwraca typ = klasa „pandas.core.frame.DataFrame”. Czy jest jakaś szansa, aby wyjaśnić różnicę i kiedy każda metoda jest odpowiednia? Z góry dziękuję :)
Optimesh

oba są podobne, from_dictma orient kwarg, więc mógłbym go użyć, gdybym chciał uniknąć transpozycji. Istnieje kilka opcji from_dict, pod maską nie różni się tak naprawdę od używania konstruktora DataFrame.
Andy Hayden

54
Widzę pandas.core.common.PandasError: DataFrame constructor not properly called!z pierwszego przykładu
allthesignals

18
@allthesignals dodawanie list () wokół d.items działa: pd.DataFrame (list (d.items ()), columns = ['Date', 'DateValue'])
sigurdb

141

Konwertując słownik na ramkę danych pandy, w której chcesz, aby klucze były kolumnami wspomnianej ramki danych, a wartości były wartościami wierszy, możesz po prostu umieścić nawiasy wokół słownika w następujący sposób:

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

Uratowało mnie to od bólu głowy, więc mam nadzieję, że pomoże komuś tam!

EDYCJA: W dokumentach pandas jedną z opcji dataparametru w konstruktorze DataFrame jest lista słowników. Tutaj podajemy listę z jednym słownikiem.


6
Tak, ja również to zrobiłem, ale dodałem .T do transpozycji.
Anton vBR

1
Działa dobrze, ale nie wiem, dlaczego musimy to zrobić w ten sposób.
hui chen

co jeśli chcę, aby jedna z tych kolumn była używana jako indeks
om tripathi 18.09.19

102

Jak wyjaśniono w innej odpowiedzi, użycie pandas.DataFrame()bezpośrednio tutaj nie będzie działać tak, jak myślisz.

Co można zrobić, to użycie pandas.DataFrame.from_dictz 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

1
czy możemy to połączyć dowolną renamemetodą, aby jednocześnie ustawić nazwy indeksu i kolumn?
Ciprian Tomoiagă

4
Słuszna uwaga. Przykładem może być: ...., orient = 'index'). Zmiana nazwy (kolumny = {0: 'foobar'})
ntg

1
Możesz także podać pandas.DataFrame.from_dict (..., orient = 'index', columns = ['foo', 'bar']), to ze źródła wymienionego powyżej .
spen.smith

Dobra uwaga, to prawda z pand .22, które były po oryginalnej odpowiedzi ... Zaktualizowałem moją odpowiedź ...
NT

69

Przekaż elementy słownika do konstruktora DataFrame i podaj nazwy kolumn. Następnie przeanalizuj Datekolumnę, aby uzyskać Timestampwartości.

Zwróć uwagę na różnicę między python 2.x a 3.x:

W python 2.x:

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

W Pythonie 3.x: (wymagający dodatkowej „listy”)

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

3
To daje mi:PandasError: DataFrame constructor not properly called!
Chris Nielsen,

18
@ChrisNielsen Prawdopodobnie używasz python3. Powinieneś spróbować:df = pd.DataFrame(list(data.items()), columns=['Date', 'DateValue'])
Viktor Kerkez

To lepsza odpowiedź, ponieważ pokazuje, co należy zrobić w Pythonie 3.
ifly6


10

Pandy mają wbudowaną funkcję konwersji dict na ramkę danych.

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

Dla swoich danych możesz je przekonwertować jak poniżej:

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)

2
To naprawdę złe rozwiązanie, ponieważ zapisuje klucze słownika jako indeks.
Ekonomista


5

Możesz także po prostu przekazać klucze i wartości słownika do nowej ramki danych, na przykład:

import pandas as pd

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

5

W moim przypadku chciałem, aby klucze i wartości dict były kolumnami i wartościami DataFrame. Więc jedyną rzeczą, która działała dla mnie było:

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)

5

To działało dla mnie, ponieważ chciałem mieć osobną kolumnę indeksu

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

3

Akceptuje dict jako argument i zwraca ramkę danych z kluczami dict jako indeksem, a wartości jako kolumną.

def dict_to_df(d):
    df=pd.DataFrame(d.items())
    df.set_index(0, inplace=True)
    return df

zrobić dyktand, zwraca ramkę danych
najpierw

3

Tak to dla mnie działało:

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

mam nadzieję, że to pomoże


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

Jeśli nie umieścisz w yourDict.keys()środku list(), skończysz z wszystkimi kluczami i wartościami umieszczonymi w każdym rzędzie każdej kolumny. Lubię to:

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...

Ale po dodaniu list()wynik wygląda następująco:

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 ...


0

Natknąłem się na to kilka razy i mam przykładowy słownik, który utworzyłem z funkcji get_max_Path(), i zwraca przykładowy słownik:

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

Aby przekonwertować to na ramkę danych, uruchomiłem następujące:

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

Zwraca prostą dwukolumnową ramkę danych z oddzielnym indeksem:

index 0 0 2 0.309750 1 3 0.441318

Po prostu zmień nazwę kolumn za pomocą f.rename(columns={'index': 'Column1', 0: 'Column2'}, inplace=True)


0

Myślę, że można wprowadzić pewne zmiany w formacie danych podczas tworzenia słownika, a następnie łatwo przekonwertować go na DataFrame:

Wejście:

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

wynik:

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

Wejście:

aframe=DataFrame(a)

wyjście: będzie twoją ramką danych

Wystarczy użyć edycji tekstu w Sublime lub Excelu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.