Konstruuj pandy DataFrame z listy krotek (row, col, values)

81

Mam listę takich krotek

data = [
('r1', 'c1', avg11, stdev11),
('r1', 'c2', avg12, stdev12),
('r2', 'c1', avg21, stdev21),
('r2', 'c2', avg22, stdev22)
]

i chciałbym umieścić je w pandach DataFrame z wierszami nazwanymi przez pierwszą kolumnę i kolumnami nazwanymi przez drugą kolumnę. Wygląda na to, że sposób dbania o nazwy wierszy jest podobny, pandas.DataFrame([x[1:] for x in data], index = [x[0] for x in data])ale jak zadbać o kolumny, aby uzyskać macierz 2x2 (wyjście z poprzedniego zestawu to 3x4)? Czy istnieje bardziej inteligentny sposób dbania o etykiety wierszy, zamiast ich jawnego pomijania?

EDYTUJ Wygląda na to, że będę potrzebować 2 ramek DataFrames - jednej dla średnich i jednej dla odchyleń standardowych, czy to prawda? Czy mogę przechowywać listę wartości w każdej „komórce”?

gt6989b
źródło
1
Zdecydowany duplikat < stackoverflow.com/questions/11415701/… >
ely
2
@EMS wcale nie. Widziałem to pytanie, nie potrzebował obracania w 2D.
gt6989b
Nie zgadzam się - myślę, że po prostu nie jesteś zaznajomiony z właściwym sposobem układania danych w DataFrame. Generalnie, że chcesz korzystać z informacji w obu swoich kolumny 1 i 2 jako indeksów, dzięki czemu można szybko wyszukać dane przez każdą. Rzeczy w kolumnie 2 nie należą do nazw kolumn, ale nawet jeśli tak, jest to zupełnie odrębne pytanie niż tytuł twojego postu. Przypuszczam, że edycja tytułu mogłaby pomóc (choć nadal uważam, że nie jest to znacząco odmienne pytanie).
ely
1
@ely, gt6989b Zmieniłem tytuł tego „... z listy krotek (wiersz, kolumna, wartości)”, aby wyjaśnić, dlaczego nie jest to duplikat „… z krotek”
smci

Odpowiedzi:

65

Możesz przestawić ramkę DataFrame po utworzeniu:

>>> df = pd.DataFrame(data)
>>> df.pivot(index=0, columns=1, values=2)
# avg DataFrame
1      c1     c2
0               
r1  avg11  avg12
r2  avg21  avg22
>>> df.pivot(index=0, columns=1, values=3)
# stdev DataFrame
1        c1       c2
0                   
r1  stdev11  stdev12
r2  stdev21  stdev22
Roman Pekar
źródło
3
Wiersz z indeksem 0i kolumna z nazwą 1nie są zbyt piękne ...
drevicko
49

Uważam, że lepiej zostawić swoje dane ułożone tak, jak są:

df = pandas.DataFrame(data, columns=['R_Number', 'C_Number', 'Avg', 'Std'])

# Possibly also this if these can always be the indexes:
# df = df.set_index(['R_Number', 'C_Number'])

Wtedy powiedzenie jest nieco bardziej intuicyjne

df.set_index(['R_Number', 'C_Number']).Avg.unstack(level=1)

W ten sposób jest domniemane, że chcesz zmienić kształt średnich lub odchyleń standardowych. Mając na uwadze, że samo użycie pivotjest oparte wyłącznie na konwencji kolumnowej dotyczącej tego, jaką istotę semantyczną przekształcasz.

ely
źródło
1
+1, użyteczna jawność. Jestem wyraźnie zainteresowany tabelą 2D - aby umożliwić mi wyszukiwanie wartości indeksowanych zarówno przez listy wierszy, jak i kolumn, a także uzyskać dostęp do każdego z wymiarów oddzielnie. Czy możesz to zrobić ze skumulowanymi danymi?
gt6989b
2
Tak. Znacznie lepiej w przypadku danych skumulowanych. Pomyśl o tabeli relacyjnej bazy danych, takiej jak SQL. Nie rozbijasz całej kolumny na kilka powtarzających się kolumn, prawda? Powinno to mieć miejsce tylko w szczególnych przypadkach (myślę, że jest to wzór od wysokiego do szerokiego). Zwykle traktujesz wiele kolumn jako indeksy i dokonujesz selekcji, częściowo wiążąc jedną z kolumn indeksu lub wiążąc je wszystkie w celu uzyskania określonego rekordu.
ely
2
Więc w twoim przypadku po ustawieniu indeksu na [R_Number, C_Number]możesz df.ix[('r1','c2')]na przykład zrobić . Możesz też pozostawić je jako zwykłe kolumny i użyć indeksowania logicznego:df[(df.R_Number == 'r1') & (df.C_Number == 'c2')]
ely
2
Ogólnie rzecz biorąc, głównym przypadkiem użycia podczas robienia tego, z czym próbujesz zrobić, pivotjest formatowanie jakiejś tabeli tak, aby była ładnie drukowana na ekranie lub ładnie eksportowana do HTML, LaTeX lub .csv, czy coś takiego. Podobnie jak formatowanie tabeli, która zostanie przesłana do prezentacji lub artykułu. W przeciwnym razie, jeśli chodzi o efektywne manipulowanie danymi, chcesz, aby rzeczy były wielindeksami, kiedy możesz (na przykład klucze do tabeli bazy danych) lub przynajmniej jako powtarzające się kolumny, abyś mógł wykonywać wydajne indeksowanie i łączenie itp. Ale tego nie robisz. chcą wysadzić ich we własne kolumny.
ely
35

Oto, czego się spodziewałem, kiedy doszedłem do tego pytania:

#!/usr/bin/env python

import pandas as pd


df = pd.DataFrame([(1, 2, 3, 4),
                   (5, 6, 7, 8),
                   (9, 0, 1, 2),
                   (3, 4, 5, 6)],
                  columns=list('abcd'),
                  index=['India', 'France', 'England', 'Germany'])
print(df)

daje

         a  b  c  d
India    1  2  3  4
France   5  6  7  8
England  9  0  1  2
Germany  3  4  5  6
Martin Thoma
źródło
Źle przeczytałeś pytanie. Dane pierwotnie podane w pytaniu mają już etykiety wierszy i kolumn dla każdego rozpatrywanego rekordu.
gt6989b
11
@ gt6989b Nie, nie zrobiłem. Nie próbowałem odpowiedzieć na pierwotne pytanie, ale pytanie, które ludzie (mogą) zadawać, kiedy wchodzą na tę stronę.
Martin Thoma,
8
@MartinThoma Dzięki, rzeczywiście tego szukam na tej stronie.
słowo