Konstruowanie pand DataFrame z wartości w zmiennych daje „ValueError: Jeśli używasz wszystkich wartości skalarnych, musisz przekazać indeks”


370

To może być proste pytanie, ale nie mogę wymyślić, jak to zrobić. Powiedzmy, że mam dwie zmienne w następujący sposób.

a = 2
b = 3

Chcę zbudować DataFrame z tego:

df2 = pd.DataFrame({'A':a,'B':b})

To generuje błąd:

ValueError: Jeśli używasz wszystkich wartości skalarnych, musisz przekazać indeks

Próbowałem tego także:

df2 = (pd.DataFrame({'a':a,'b':b})).reset_index()

Daje to ten sam komunikat o błędzie.

Odpowiedzi:


570

Komunikat o błędzie mówi, że jeśli przekazujesz wartości skalarne, musisz przekazać indeks. Nie możesz więc użyć wartości skalarnych dla kolumn - np. Użyj listy:

>>> df = pd.DataFrame({'A': [a], 'B': [b]})
>>> df
   A  B
0  2  3

lub użyj wartości skalarnych i przekaż indeks:

>>> df = pd.DataFrame({'A': a, 'B': b}, index=[0])
>>> df
   A  B
0  2  3

7
Być może dzieje się tak, ponieważ kolejność elementów na liście w Pythonie jest trwała, podczas gdy kolejność elementów w słowniku nie. Można utworzyć instancję DataFrame z pustym słownikiem. Zasadniczo przypuszczam, że pokazana tutaj jednorzędowa ramka DataFrame mogłaby być również zbudowana ze słownika, ponieważ kolejność nie ma znaczenia (ale nie została zaimplementowana). Jednak w przypadku wielu wierszy Pandy nie byłyby w stanie utworzyć DataFrame, ponieważ nie wiedziałby, które elementy należały do ​​tego samego wiersza.
Alexander

2
@VitalyIsaev - W takim przypadku wiersz ramki danych (reprezentowany przez dany słownik) nie ma indeksu (nawet domyślnego). Prostym rozwiązaniem jest zawinięcie słownika w listę, która ma „naturalne indeksowanie”. Można twierdzić, że jeśli podano tylko jeden słownik (bez listy zawijania), to załóżmy index=0, ale może to prowadzić do przypadkowego niewłaściwego użycia (myśląc, że pojedynczy słownik może w jakiś sposób stworzyć ramkę danych z wieloma wierszami)
Ori

kilka rozwiązań w tym linku eulertech.wordpress.com/2017/11/28/…
Jason Gol

Powodem tego jest to, że DataFrames są przeznaczone do przechowywania danych dwuwymiarowych (tj. Wierszy dwóch zmiennych OP). Jeśli chcesz po prostu trzymać indeks -> pary wartości (jak słownik), powinieneś użyć Serii, jak sugeruje Rob .
Danuker

Jest to ramka danych z pojedynczą próbką / wierszem, więc indeks = [0] ma logiczny sens; ale można również zmanipulować go, aby był indeksem = [100], co działa. P: Czy indeks nie powinien być logicznie porządkowany przyrostowo, dlaczego python pozwala na manipulowanie indeksem?
Sumanth Lazarus

65

Możesz także użyć pd.DataFrame.from_recordswygodniejszego, gdy masz już pod ręką słownik:

df = pd.DataFrame.from_records([{ 'A':a,'B':b }])

Możesz także ustawić indeks, jeśli chcesz:

df = pd.DataFrame.from_records([{ 'A':a,'B':b }], index='A')

27
Ta odpowiedź nie działa dla mnie - przy użyciu from_records pojawia się ten sam komunikat o błędzie.
Dave Kielpinski

Dave, próbowałeś fragmentu kodu (oczywiście zdefiniuj aib)? Czy nadal pojawia się komunikat o błędzie? Czy możesz pisać?
fAX

12
@DaveKielpinski Czy zapomniałeś dodać nawiasy?
Dennis

Spowoduje to użycie klawiszy dict jako nazw kolumn. Jak ustawić klucze do indeksowania?
mingchau

@DaveKielpinski Sprawdź, czy przekazałeś listę do metody „from_records”; w przeciwnym razie nie będzie działać, a otrzymasz ten sam komunikat o błędzie, jak podczas wywoływania DataFrame w słowniku.
mairan

55

Najpierw musisz utworzyć serię pand. Drugim krokiem jest konwersja serii pand na ramkę danych pand.

import pandas as pd
data = {'a': 1, 'b': 2}
pd.Series(data).to_frame()

Możesz nawet podać nazwę kolumny.

pd.Series(data).to_frame('ColumnName')

1
To zadziałało dla mnie. Mój słownik miał klucze całkowite i wartości ndarray.
StatsSorceress

pd.Series(data).to_frame('ColumnName')jest krótszy, chociaż ten odpowiednik jest być może bardziej bezpośredni:pd.DataFrame.from_dict(data, orient='index', columns=['ColumnName'])
Alex F

29

Możesz spróbować zapakować słownik do listy

my_dict = {'A':1,'B':2}

pd.DataFrame([my_dict])

   A  B
0  1  2

8

Może Series zapewni wszystkie potrzebne funkcje:

pd.Series({'A':a,'B':b})

DataFrame można traktować jako zbiór serii, dlatego możesz:

  • Połącz wiele serii w jedną ramkę danych (jak opisano tutaj )

  • Dodaj zmienną Series do istniejącej ramki danych ( przykład tutaj )


7

Musisz podać iterowalne wartości dla kolumn Pandas DataFrame:

df2 = pd.DataFrame({'A':[a],'B':[b]})

6

Miałem ten sam problem z tablicami numpy i rozwiązaniem jest ich spłaszczenie:

data = {
    'b': array1.flatten(),
    'a': array2.flatten(),
}

df = pd.DataFrame(data)

3

Jeśli zamierzasz przekonwertować słownik skalarów, musisz dołączyć indeks:

import pandas as pd

alphabets = {'A': 'a', 'B': 'b'}
index = [0]
alphabets_df = pd.DataFrame(alphabets, index=index)
print(alphabets_df)

Chociaż indeks nie jest wymagany dla słownika list, ten sam pomysł można rozszerzyć na słownik list:

planets = {'planet': ['earth', 'mars', 'jupiter'], 'length_of_day': ['1', '1.03', '0.414']}
index = [0, 1, 2]
planets_df = pd.DataFrame(planets, index=index)
print(planets_df)

Oczywiście w przypadku słownika list można zbudować ramkę danych bez indeksu:

planets_df = pd.DataFrame(planets)
print(planets_df)

3

Możesz spróbować:

df2 = pd.DataFrame.from_dict({'a':a,'b':b}, orient = 'index')

Z dokumentacji argumentu „orient”: jeśli kluczami przekazanego dict powinny być kolumny wynikowej DataFrame, przekaż „kolumny” (domyślnie). W przeciwnym razie, jeśli klucze powinny być wierszami, należy przekazać „indeks”.


Użyj narzędzi do formatowania, aby poprawnie edytować i sformatować pytanie / odpowiedź. Kody w zdaniach mają być sformatowane jako code Bardzo ważne słowa, aby były pogrubione , mniej ważne kursywa Kursywa W razie potrzeby używaj także list
Morse

To nie rozwiązuje zadanego pytania, daje inny wynik niż pożądany.
Ken Williams

3

Magia pand w pracy. Cała logika jest wyłączona.

Komunikat o błędzie "ValueError: If using all scalar values, you must pass an index"mówi, że musisz przekazać indeks.

Nie musi to oznaczać, że przekazanie indeksu powoduje, że pandy robią to, co chcesz

Po przejściu indeksu pandy będą traktować klucze słownika jako nazwy kolumn, a wartości jak to, co kolumna powinna zawierać dla każdej wartości w indeksie.

a = 2
b = 3
df2 = pd.DataFrame({'A':a,'B':b}, index=[1])

    A   B
1   2   3

Przekazywanie większego indeksu:

df2 = pd.DataFrame({'A':a,'B':b}, index=[1, 2, 3, 4])

    A   B
1   2   3
2   2   3
3   2   3
4   2   3

Indeks jest zwykle generowany automatycznie przez ramkę danych, gdy nie jest podany. Jednak pandy nie wiedzą, ile rzędów 2i 3chcesz. Możesz jednak wyrazić się bardziej otwarcie

df2 = pd.DataFrame({'A':[a]*4,'B':[b]*4})
df2

    A   B
0   2   3
1   2   3
2   2   3
3   2   3

Domyślny indeks wynosi 0.

Podczas tworzenia ramek danych zalecałbym zawsze przekazywanie słownika list do konstruktora ramki danych. Łatwiej jest czytać innym programistom. Panda ma wiele ostrzeżeń, nie zmuszaj innych programistów, by czytali Twój kod.


3

dane wejściowe nie muszą być listą rekordów - może to być także pojedynczy słownik:

pd.DataFrame.from_records({'a':1,'b':2}, index=[0])
   a  b
0  1  2

Co wydaje się równoważne z:

pd.DataFrame({'a':1,'b':2}, index=[0])
   a  b
0  1  2

2

Wynika to z faktu, że DataFrame ma dwa intuicyjne wymiary - kolumny i wiersze.

Podajesz kolumny tylko przy użyciu kluczy słownika.

Jeśli chcesz określić tylko dane jednowymiarowe, użyj serii!


0

Konwertuj słownik na ramkę danych

col_dict_df = pd.Series(col_dict).to_frame('new_col').reset_index()

Nadaj nową nazwę kolumnie

col_dict_df.columns = ['col1', 'col2']

-2

Jeśli masz słownik, możesz przekształcić go w ramkę danych pand za pomocą następującego wiersza kodu:

pd.DataFrame({"key": d.keys(), "value": d.values()})

Działa, ale IMHO nie ma większego sensu <code> `<! - language: lang-py -> fruits_count = defaultdict (int) fruits_count [" apples "] = 10 fruits_count [" bananas "] = 21 pd.DataFrame ({"key": fruits_count.keys (), "value": fruits_count.values ​​()}) Out: wartość klucza 0 (banany, jabłka) (21, 10) 1 (banany, jabłka) (21, 10) <kod>
Emiter

-3

Wystarczy przekazać dyktando na liście:

a = 2
b = 3
df2 = pd.DataFrame([{'A':a,'B':b}])
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.