Jakie są argumenty' poziomów',' kluczy ' i nazw w funkcji concat Pandy?

Pytania

  • Jak używać pd.concat?
  • do czego służy argument levels?
  • do czego służy argument keys?
  • czy istnieje kilka przykładów, które pomogą wyjaśnić, jak używać wszystkich argumentów?

Funkcja Pandas' concat jest szwajcarskim nożem wojskowym łączących się narzędzi. Różnorodność sytuacji, w których jest to przydatne, jest wiele. Istniejąca dokumentacja pozostawia kilka szczegółów na temat niektórych opcjonalnych argumenty. Wśród nich są argumenty levels i keys. Postanowiłem dowiedzieć się, do czego służą te argumenty.

Zadam pytanie, które będzie stanowić bramę do wielu aspektów pd.concat.

Rozważmy ramki danychd1, d2, i d3:

import pandas as pd

d1 = pd.DataFrame(dict(A=.1, B=.2, C=.3), [2, 3])
d2 = pd.DataFrame(dict(B=.4, C=.5, D=.6), [1, 2])
d3 = pd.DataFrame(dict(A=.7, B=.8, D=.9), [1, 3])

Gdybym połączył je razem z

pd.concat([d1, d2, d3], keys=['d1', 'd2', 'd3'])

Otrzymuję oczekiwany wynik z pandas.MultiIndex dla mojego columns obiektu:

        A    B    C    D
d1 2  0.1  0.2  0.3  NaN
   3  0.1  0.2  0.3  NaN
d2 1  NaN  0.4  0.5  0.6
   2  NaN  0.4  0.5  0.6
d3 1  0.7  0.8  NaN  0.9
   3  0.7  0.8  NaN  0.9

Jednak chciałem użyć levels argument dokumentacja :

Poziomy : lista sekwencji, domyślnie None. Specyficzne poziomy (unikalne wartości) do wykorzystania przy konstruowaniu MultiIndex. W przeciwnym razie zostaną one wywnioskowane z kluczy.

Więc zdałem

pd.concat([d1, d2, d3], keys=['d1', 'd2', 'd3'], levels=[['d1', 'd2']])

I dostać KeyError

ValueError: Key d3 not in level Index(['d1', 'd2'], dtype='object')

To miało sens. Poziomy, które przeszedłem, były niewystarczające do opisania niezbędnych poziomów wskazanych przez klawisze. Gdybym nic nie przeszedł, tak jak wyżej, poziomy są wnioskowane (zgodnie z dokumentacją). Ale jak inaczej mogę użyć tego argumentu do lepszego efektu?

If I tried this instead:

pd.concat([d1, d2, d3], keys=['d1', 'd2', 'd3'], levels=[['d1', 'd2', 'd3']])

I otrzymałem takie same wyniki jak powyżej. Ale kiedy dodam jeszcze jedną wartość do poziomów,

df = pd.concat([d1, d2, d3], keys=['d1', 'd2', 'd3'], levels=[['d1', 'd2', 'd3', 'd4']])

Kończę z tą samą ramką danych, ale wynik MultiIndex mA nieużywany poziom.

df.index.levels[0]

Index(['d1', 'd2', 'd3', 'd4'], dtype='object')

Więc jaki jest sens argumentu level i czy powinienem używać keys inaczej?

Używam Pythona 3.6 i Pandy 0.22

 101
Author: Anton Protopopov, 2018-04-03

1 answers

W trakcie odpowiadania na to pytanie nauczyłem się wielu rzeczy i chciałem złożyć katalog przykładów i wyjaśnienia.

Konkretna odpowiedź na argument levels nadejdzie pod koniec.

pandas.concat: The Missing Manual

Link Do Aktualnej Dokumentacji

Import i definiowanie obiektów

import pandas as pd

d1 = pd.DataFrame(dict(A=.1, B=.2, C=.3), index=[2, 3])
d2 = pd.DataFrame(dict(B=.4, C=.5, D=.6), index=[1, 2])
d3 = pd.DataFrame(dict(A=.7, B=.8, D=.9), index=[1, 3])

s1 = pd.Series([1, 2], index=[2, 3])
s2 = pd.Series([3, 4], index=[1, 2])
s3 = pd.Series([5, 6], index=[1, 3])

Argumenty

objs

Pierwszy argument natykamy się na to objs:

Objs : Sekwencja lub mapowanie szeregów, ramek danych lub obiektów panelowych Jeśli dict zostanie przekazany, sortowane klucze zostaną użyte jako argument keys, chyba że zostanie przekazany, w takim przypadku zostaną wybrane wartości(patrz poniżej). Wszystkie obiekty None zostaną upuszczone po cichu, chyba że wszystkie są None, w którym to przypadku zostanie podniesiony ValueError

  • zazwyczaj widzimy to używane z listą Series lub DataFrame obiektów.
  • pokażę, że dict może być również bardzo przydatna.
  • Generatory mogą być również używane i mogą być przydatne przy użyciu map jak w map(f, list_of_df)

Na razie pozostaniemy przy liście niektórych obiektów DataFrame i Series zdefiniowanych powyżej. Później pokażę, w jaki sposób można wykorzystać słowniki, aby dać bardzo przydatne wyniki MultiIndex.

pd.concat([d1, d2])

     A    B    C    D
2  0.1  0.2  0.3  NaN
3  0.1  0.2  0.3  NaN
1  NaN  0.4  0.5  0.6
2  NaN  0.4  0.5  0.6

axis

Drugi argument, z którym się spotykamy, to axis której wartością domyślną jest 0:

: {0/'index', 1 / 'columns'}, default 0 Oś do konkatenacji wzdłuż.

Dwa DataFrame S z axis=0 (ułożone)

Dla wartości 0 lub index mamy na myśli: "Wyrównaj wzdłuż kolumn i dodaj do indeksu".

Jak pokazano powyżej, gdzie użyliśmy axis=0, ponieważ 0 jest wartością domyślną i widzimy, że indeks d2 rozszerza indeks d1 pomimo nakładania się wartości 2:

pd.concat([d1, d2], axis=0)

     A    B    C    D
2  0.1  0.2  0.3  NaN
3  0.1  0.2  0.3  NaN
1  NaN  0.4  0.5  0.6
2  NaN  0.4  0.5  0.6

Dwa DataFrame S z axis=1 (obok siebie)

Dla wartości 1 lub columns mamy na myśli: "Wyrównaj wzdłuż indeksu i dodaj do kolumn",

pd.concat([d1, d2], axis=1)

     A    B    C    B    C    D
1  NaN  NaN  NaN  0.4  0.5  0.6
2  0.1  0.2  0.3  0.4  0.5  0.6
3  0.1  0.2  0.3  NaN  NaN  NaN

Widzimy, że wynikowy indeks jest związkiem indeksów, a wynikowe kolumny są rozszerzeniem kolumn z d1 o kolumny z d2.

Dwa (lub trzy) Series z axis=0 (ułożone)

Po połączeniu pandas.Series wzdłuż axis=0, otrzymujemy pandas.Series. Nazwa wynik {[37] } będzie None, chyba że wszystkie Series połączone mają tę samą nazwę. Zwróć uwagę na 'Name: A' kiedy wydrukujemy wynik Series. Gdy nie jest obecny, możemy założyć, że Series nazwa to None.

               |                       |                        |  pd.concat(
               |  pd.concat(           |  pd.concat(            |      [s1.rename('A'),
 pd.concat(    |      [s1.rename('A'), |      [s1.rename('A'),  |       s2.rename('B'),
     [s1, s2]) |       s2])            |       s2.rename('A')]) |       s3.rename('A')])
-------------- | --------------------- | ---------------------- | ----------------------
2    1         | 2    1                | 2    1                 | 2    1
3    2         | 3    2                | 3    2                 | 3    2
1    3         | 1    3                | 1    3                 | 1    3
2    4         | 2    4                | 2    4                 | 2    4
dtype: int64   | dtype: int64          | Name: A, dtype: int64  | 1    5
               |                       |                        | 3    6
               |                       |                        | dtype: int64

Dwa (lub trzy) Series Z axis=1 (obok siebie)

Podczas łączenia pandas.Series wzdłuż axis=1, jest to atrybut name, do którego się odwołujemy, aby wywnioskować nazwę kolumny w wynikowym pandas.DataFrame.

                       |                       |  pd.concat(
                       |  pd.concat(           |      [s1.rename('X'),
 pd.concat(            |      [s1.rename('X'), |       s2.rename('Y'),
     [s1, s2], axis=1) |       s2], axis=1)    |       s3.rename('Z')], axis=1)
---------------------- | --------------------- | ------------------------------
     0    1            |      X    0           |      X    Y    Z
1  NaN  3.0            | 1  NaN  3.0           | 1  NaN  3.0  5.0
2  1.0  4.0            | 2  1.0  4.0           | 2  1.0  4.0  NaN
3  2.0  NaN            | 3  2.0  NaN           | 3  2.0  NaN  6.0

Mieszane Series i DataFrame z axis=0 (stacked)

Podczas wykonywania konkatenacji Series i DataFrame wzdłuż axis=0, zamieniamy wszystkie {[37] } na pojedyncze kolumny DataFrame s.

Zwróć szczególną uwagę, że jest to konkatenacja wzdłuż axis=0; oznacza to wydłużenie indeksu (wierszy) przy wyrównywaniu kolumn. W poniższych przykładach widzimy, że indeks staje się [2, 3, 2, 3], który jest masowym dodawaniem indeksów. Kolumny nie nakładają się, chyba że wymuszę nazwanie Series kolumny z argumentem do to_frame:

 pd.concat(               |
     [s1.to_frame(), d1]) |  pd.concat([s1, d1])
------------------------- | ---------------------
     0    A    B    C     |      0    A    B    C
2  1.0  NaN  NaN  NaN     | 2  1.0  NaN  NaN  NaN
3  2.0  NaN  NaN  NaN     | 3  2.0  NaN  NaN  NaN
2  NaN  0.1  0.2  0.3     | 2  NaN  0.1  0.2  0.3
3  NaN  0.1  0.2  0.3     | 3  NaN  0.1  0.2  0.3

Widać, że wyniki pd.concat([s1, d1]) są takie same, jak gdybym sam perfromował to_frame.

Jednak mogę kontrolować nazwę wynikowej kolumny z parametrem to_frame. Zmiana nazwy Series metodą rename powoduje, że nie kontroluje nazwę kolumny w wynikowym DataFrame.

 # Effectively renames       |                            |
 # `s1` but does not align   |  # Does not rename.  So    |  # Renames to something
 # with columns in `d1`      |  # Pandas defaults to `0`  |  # that does align with `d1`
 pd.concat(                  |  pd.concat(                |  pd.concat(
     [s1.to_frame('X'), d1]) |      [s1.rename('X'), d1]) |      [s1.to_frame('B'), d1])
---------------------------- | -------------------------- | ----------------------------
     A    B    C    X        |      0    A    B    C      |      A    B    C
2  NaN  NaN  NaN  1.0        | 2  1.0  NaN  NaN  NaN      | 2  NaN  1.0  NaN
3  NaN  NaN  NaN  2.0        | 3  2.0  NaN  NaN  NaN      | 3  NaN  2.0  NaN
2  0.1  0.2  0.3  NaN        | 2  NaN  0.1  0.2  0.3      | 2  0.1  0.2  0.3
3  0.1  0.2  0.3  NaN        | 3  NaN  0.1  0.2  0.3      | 3  0.1  0.2  0.3

Mieszane Series i DataFrame Z axis=1 (obok siebie)

To dość intuicyjne. Series nazwa kolumny domyślnie oznacza wyliczenie takie obiekty Series, gdy atrybut name nie jest dostępny.
                    |  pd.concat(
 pd.concat(         |      [s1.rename('X'),
     [s1, d1],      |       s2, s3, d1],
     axis=1)        |      axis=1)
------------------- | -------------------------------
   0    A    B    C |      X    0    1    A    B    C
2  1  0.1  0.2  0.3 | 1  NaN  3.0  5.0  NaN  NaN  NaN
3  2  0.1  0.2  0.3 | 2  1.0  4.0  NaN  0.1  0.2  0.3
                    | 3  2.0  NaN  6.0  0.1  0.2  0.3

join

Trzeci argument to join opisuje, czy wynikowe scalenie powinno być scaleniem zewnętrznym (domyślnym) czy scaleniem wewnętrznym.

W związku z tym, że nie jest to możliwe, nie jest to możliwe.]} Jak obsługiwać indeksy na innych osiach.

Okazuje się, że nie ma opcji left lub right, ponieważ pd.concat może obsłużyć więcej niż tylko dwa obiekty do scalenia.

W przypadku d1 i d2 opcje wyglądają następująco:

outer

pd.concat([d1, d2], axis=1, join='outer')

     A    B    C    B    C    D
1  NaN  NaN  NaN  0.4  0.5  0.6
2  0.1  0.2  0.3  0.4  0.5  0.6
3  0.1  0.2  0.3  NaN  NaN  NaN

inner

pd.concat([d1, d2], axis=1, join='inner')

     A    B    C    B    C    D
2  0.1  0.2  0.3  0.4  0.5  0.6

join_axes

Czwarty argument jest rzeczą, która pozwala nam zrobić nasze left połączyć i więcej.

Join_axes : lista obiektów indeksu
Specyficzne indeksy do wykorzystania dla innych osi n-1 zamiast wykonywania wewnętrznej / zewnętrznej logiki zestawu.

Left Merge

pd.concat([d1, d2, d3], axis=1, join_axes=[d1.index])

     A    B    C    B    C    D    A    B    D
2  0.1  0.2  0.3  0.4  0.5  0.6  NaN  NaN  NaN
3  0.1  0.2  0.3  NaN  NaN  NaN  0.7  0.8  0.9

Right Merge

pd.concat([d1, d2, d3], axis=1, join_axes=[d3.index])

     A    B    C    B    C    D    A    B    D
1  NaN  NaN  NaN  0.4  0.5  0.6  0.7  0.8  0.9
3  0.1  0.2  0.3  NaN  NaN  NaN  0.7  0.8  0.9

ignore_index

Ignore_index: boolean, default False
Jeśli True, nie używaj wartości indeksu wzdłuż osi konkatenacji. Uzyskana oś będzie oznaczona jako 0, ..., n-1. Jest to przydatne w przypadku łączenia obiektów, w których oś konkatenacji nie zawiera znaczących informacji o indeksowaniu. Uwaga wartości indeksu na pozostałych osiach są nadal przestrzegane w Dołącz.

Tak jak wtedy, gdy stosuję d1 na górze d2, jeśli nie dbam o wartości indeksu, mogę je zresetować lub zignorować.

                      |  pd.concat(             |  pd.concat(
                      |      [d1, d2],          |      [d1, d2]
 pd.concat([d1, d2])  |      ignore_index=True) |  ).reset_index(drop=True)
--------------------- | ----------------------- | -------------------------
     A    B    C    D |      A    B    C    D   |      A    B    C    D
2  0.1  0.2  0.3  NaN | 0  0.1  0.2  0.3  NaN   | 0  0.1  0.2  0.3  NaN
3  0.1  0.2  0.3  NaN | 1  0.1  0.2  0.3  NaN   | 1  0.1  0.2  0.3  NaN
1  NaN  0.4  0.5  0.6 | 2  NaN  0.4  0.5  0.6   | 2  NaN  0.4  0.5  0.6
2  NaN  0.4  0.5  0.6 | 3  NaN  0.4  0.5  0.6   | 3  NaN  0.4  0.5  0.6

I przy użyciu axis=1:

                                   |     pd.concat(
                                   |         [d1, d2], axis=1,
 pd.concat([d1, d2], axis=1)       |         ignore_index=True)
-------------------------------    |    -------------------------------
     A    B    C    B    C    D    |         0    1    2    3    4    5
1  NaN  NaN  NaN  0.4  0.5  0.6    |    1  NaN  NaN  NaN  0.4  0.5  0.6
2  0.1  0.2  0.3  0.4  0.5  0.6    |    2  0.1  0.2  0.3  0.4  0.5  0.6
3  0.1  0.2  0.3  NaN  NaN  NaN    |    3  0.1  0.2  0.3  NaN  NaN  NaN

keys

Możemy przekazać listę wartości skalarnych lub krotek w celu przypisania wartości krotek lub skalarów do odpowiedniego MultiIndex. Długość przekazywanej listy musi być taka sama jak liczba elementów, które są łączone.

Keys : sequence, default None
Jeśli przeszedł wiele poziomów, powinien zawierać krotki. Struktura hierarchicznego indeksu za pomocą przekazywanych kluczy jako zewnętrznego poziomu

axis=0

Podczas łączenia Series obiektów wzdłuż axis=0 (Rozszerzanie indeksu).

Te klucze stają się nowym początkowym poziomem obiektu MultiIndex w atrybucie index.

 #           length 3             length 3           #         length 2        length 2
 #          /--------\         /-----------\         #          /----\         /------\
 pd.concat([s1, s2, s3], keys=['A', 'B', 'C'])       pd.concat([s1, s2], keys=['A', 'B'])
----------------------------------------------      -------------------------------------
A  2    1                                           A  2    1
   3    2                                              3    2
B  1    3                                           B  1    3
   2    4                                              2    4
C  1    5                                           dtype: int64
   3    6
dtype: int64

Możemy jednak użyć więcej niż wartości skalarne w argumencie keys, aby utworzyć jeszcze głębiej MultiIndex. Tutaj mijamy tuples długości 2 poprzedzają dwa nowe poziomy MultiIndex:

 pd.concat(
     [s1, s2, s3],
     keys=[('A', 'X'), ('A', 'Y'), ('B', 'X')])
-----------------------------------------------
A  X  2    1
      3    2
   Y  1    3
      2    4
B  X  1    5
      3    6
dtype: int64

axis=1

Jest nieco inaczej, gdy rozciąga się wzdłuż kolumn. Kiedy użyliśmy axis=0 (patrz wyżej) nasze keys działały jako MultiIndex poziomy oprócz istniejącego indeksu. Dla axis=1, mamy na myśli oś, której Series obiekty nie mają, a mianowicie atrybut columns.

Wariacje dwóch Series wtih axis=1

Zauważ, że nazwanie s1 i s2 ma znaczenie tak długo, jak nie keys są przekazywane, ale staje się overridden, jeśli keys są przekazywane.

               |                       |                        |  pd.concat(
               |  pd.concat(           |  pd.concat(            |      [s1.rename('U'),
 pd.concat(    |      [s1, s2],        |      [s1.rename('U'),  |       s2.rename('V')],
     [s1, s2], |      axis=1,          |       s2.rename('V')], |       axis=1,
     axis=1)   |      keys=['X', 'Y']) |       axis=1)          |       keys=['X', 'Y'])
-------------- | --------------------- | ---------------------- | ----------------------
     0    1    |      X    Y           |      U    V            |      X    Y
1  NaN  3.0    | 1  NaN  3.0           | 1  NaN  3.0            | 1  NaN  3.0
2  1.0  4.0    | 2  1.0  4.0           | 2  1.0  4.0            | 2  1.0  4.0
3  2.0  NaN    | 3  2.0  NaN           | 3  2.0  NaN            | 3  2.0  NaN
MultiIndex Z Series i axis=1
 pd.concat(
     [s1, s2],
     axis=1,
     keys=[('W', 'X'), ('W', 'Y')])
-----------------------------------
     W
     X    Y
1  NaN  3.0
2  1.0  4.0
3  2.0  NaN
Dwa DataFrame Z axis=1

Podobnie jak w przykładach axis=0, keys dodaje poziomy do MultiIndex, ale tym razem do obiektu przechowywanego w atrybucie columns.

 pd.concat(                     |  pd.concat(
     [d1, d2],                  |      [d1, d2],
     axis=1,                    |      axis=1,
     keys=['X', 'Y'])           |      keys=[('First', 'X'), ('Second', 'X')])
------------------------------- | --------------------------------------------
     X              Y           |   First           Second
     A    B    C    B    C    D |       X                X
1  NaN  NaN  NaN  0.4  0.5  0.6 |       A    B    C      B    C    D
2  0.1  0.2  0.3  0.4  0.5  0.6 | 1   NaN  NaN  NaN    0.4  0.5  0.6
3  0.1  0.2  0.3  NaN  NaN  NaN | 2   0.1  0.2  0.3    0.4  0.5  0.6
                                | 3   0.1  0.2  0.3    NaN  NaN  NaN
Series i DataFrame Z axis=1 To trudne. W tym przypadku wartość klucza skalarnego nie może działać jako jedyny poziom indeksu dla obiektu Series, gdy staje się kolumną, a także działa jako pierwszy poziom MultiIndex dla DataFrame. Tak więc Pandy ponownie użyją atrybutu name obiektu Series jako źródła nazwy kolumny.
 pd.concat(           |  pd.concat(
     [s1, d1],        |      [s1.rename('Z'), d1],
     axis=1,          |      axis=1,
     keys=['X', 'Y']) |      keys=['X', 'Y'])
--------------------- | --------------------------
   X    Y             |    X    Y
   0    A    B    C   |    Z    A    B    C
2  1  0.1  0.2  0.3   | 2  1  0.1  0.2  0.3
3  2  0.1  0.2  0.3   | 3  2  0.1  0.2  0.3
Ograniczenia keys i MultiIndex wnioskowania.

Pandy zdają się tylko wnioskować nazwy kolumn z Series name, ale nie wypełnią spacji podczas analogicznej konkatenacji pomiędzy ramkami danych o innej liczbie poziomów kolumn.

d1_ = pd.concat(
    [d1], axis=1,
    keys=['One'])
d1_

   One
     A    B    C
2  0.1  0.2  0.3
3  0.1  0.2  0.3

Następnie połącz to z inną ramką danych z tylko jedną poziom w kolumnach obiekt i pandy odmówią wykonania krotek obiektu MultiIndex i połączą wszystkie ramki danych tak, jakby był to pojedynczy poziom obiektów, skalarów i krotek.

pd.concat([d1_, d2], axis=1)

   (One, A)  (One, B)  (One, C)    B    C    D
1       NaN       NaN       NaN  0.4  0.5  0.6
2       0.1       0.2       0.3  0.4  0.5  0.6
3       0.1       0.2       0.3  NaN  NaN  NaN

Przechodząc dict zamiast list

Przekazując słownik, pandas.concat użyje kluczy ze słownika jako parametru keys.

 # axis=0               |  # axis=1
 pd.concat(             |  pd.concat(
     {0: d1, 1: d2})    |      {0: d1, 1: d2}, axis=1)
----------------------- | -------------------------------
       A    B    C    D |      0              1
0 2  0.1  0.2  0.3  NaN |      A    B    C    B    C    D
  3  0.1  0.2  0.3  NaN | 1  NaN  NaN  NaN  0.4  0.5  0.6
1 1  NaN  0.4  0.5  0.6 | 2  0.1  0.2  0.3  0.4  0.5  0.6
  2  NaN  0.4  0.5  0.6 | 3  0.1  0.2  0.3  NaN  NaN  NaN

levels

Jest to używane w połączeniu z argumentem keys.Gdy {[33] } jest pozostawiona jako wartość domyślna z None, Pandy przyjmą unikalne wartości każdego poziomu wynikowego MultiIndex i użyją go jako obiektu użytego w wynikowym atrybucie index.levels.

Poziomy : lista sekwencji, domyślnie None
Specyficzne poziomy (unikalne wartości) do wykorzystania przy konstruowaniu MultiIndex. W przeciwnym razie zostaną one wywnioskowane z kluczy.

[196]} jeśli Pandy już wnioskują, jakie powinny być te poziomy, jaka jest korzyść, aby je sami określić? Pokażę Ci przykład i pozostawić to do ciebie, aby wymyślić inne powody, dla których może to być przydatne.

Przykład

Zgodnie z dokumentacją argument levels jest listą sekwencji. Oznacza to, że możemy użyć innej pandas.Index jako jednej z tych sekwencji.

Rozważmy ramkę danych df która jest konkatenacją d1, d2 i d3:

df = pd.concat(
    [d1, d2, d3], axis=1,
    keys=['First', 'Second', 'Fourth'])

df

  First           Second           Fourth
      A    B    C      B    C    D      A    B    D
1   NaN  NaN  NaN    0.4  0.5  0.6    0.7  0.8  0.9
2   0.1  0.2  0.3    0.4  0.5  0.6    NaN  NaN  NaN
3   0.1  0.2  0.3    NaN  NaN  NaN    0.7  0.8  0.9

Poziomy obiektu columns to:

print(df, *df.columns.levels, sep='\n')

Index(['First', 'Second', 'Fourth'], dtype='object')
Index(['A', 'B', 'C', 'D'], dtype='object')

Jeśli użyjemy sum wewnątrz groupby mamy Pobierz:

df.groupby(axis=1, level=0).sum()

   First  Fourth  Second
1    0.0     2.4     1.5
2    0.6     0.0     1.5
3    0.6     2.4     0.0

Ale co by było gdyby zamiast ['First', 'Second', 'Fourth'] były inne brakujące Kategorie o nazwie Third i Fifth? I chciałem, żeby znalazły się w wynikach agregacji? Możemy to zrobić, gdybyśmy mieli pandas.CategoricalIndex. Możemy to wcześniej określić argumentem levels.

Zamiast tego zdefiniujmy df jako:
cats = ['First', 'Second', 'Third', 'Fourth', 'Fifth']
lvl = pd.CategoricalIndex(cats, categories=cats, ordered=True)

df = pd.concat(
    [d1, d2, d3], axis=1,
    keys=['First', 'Second', 'Fourth'],
    levels=[lvl]
)

df

   First  Fourth  Second
1    0.0     2.4     1.5
2    0.6     0.0     1.5
3    0.6     2.4     0.0

Ale pierwszy poziom obiektu columns to:

df.columns.levels[0]

CategoricalIndex(
    ['First', 'Second', 'Third', 'Fourth', 'Fifth'],
    categories=['First', 'Second', 'Third', 'Fourth', 'Fifth'],
    ordered=True, dtype='category')

I nasze groupby podsumowanie wygląda like:

df.groupby(axis=1, level=0).sum()

   First  Second  Third  Fourth  Fifth
1    0.0     1.5    0.0     2.4    0.0
2    0.6     1.5    0.0     0.0    0.0
3    0.6     0.0    0.0     2.4    0.0

names

Jest to używane do nazwania poziomów wynikowych MultiIndex. Długość listy names powinna odpowiadać liczbie poziomów w wynikowym MultiIndex.

Nazwy : lista, domyślnie brak
Nazwy poziomów w wynikowym indeksie hierarchicznym

 # axis=0                     |  # axis=1
 pd.concat(                   |  pd.concat(
     [d1, d2],                |      [d1, d2],
     keys=[0, 1],             |      axis=1, keys=[0, 1],
     names=['lvl0', 'lvl1'])  |      names=['lvl0', 'lvl1'])
----------------------------- | ----------------------------------
             A    B    C    D | lvl0    0              1
lvl0 lvl1                     | lvl1    A    B    C    B    C    D
0    2     0.1  0.2  0.3  NaN | 1     NaN  NaN  NaN  0.4  0.5  0.6
     3     0.1  0.2  0.3  NaN | 2     0.1  0.2  0.3  0.4  0.5  0.6
1    1     NaN  0.4  0.5  0.6 | 3     0.1  0.2  0.3  NaN  NaN  NaN
     2     NaN  0.4  0.5  0.6 |

verify_integrity

Samodzielna dokumentacja

Verify_integrity : boolean, default False
Sprawdź, czy nowa połączona oś zawiera duplikaty. Może to być bardzo kosztowne w stosunku do rzeczywistej konkatenacji danych.

Ponieważ wynikający Indeks z połączenia d1 i d2 nie jest unikalny, Nie sprawdziłby integralności.

pd.concat([d1, d2])

     A    B    C    D
2  0.1  0.2  0.3  NaN
3  0.1  0.2  0.3  NaN
1  NaN  0.4  0.5  0.6
2  NaN  0.4  0.5  0.6

I

pd.concat([d1, d2], verify_integrity=True)

> ValueError: indeksy mają nakładające się wartości: [2]

 131
Author: piRSquared,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-03 12:42:07