Während ich diese Frage für mich selbst beantwortete, lernte ich viele Dinge und wollte einen Katalog mit Beispielen und Erklärungen zusammenstellen.
Die konkrete Antwort auf den Punkt der levels
Arguments wird gegen Ende kommen.
pandas.concat
: Das fehlende Handbuch
Link zur aktuellen Dokumentation
Importiert und definiert Objekte
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])
Argumente
objs
Das erste Argument, auf das wir stoßen, ist objs
:
objs : eine Sequenz oder Zuordnung von Serien-, DataFrame- oder Panel-Objekten Wenn ein Diktat übergeben wird, werden die sortierten Schlüssel als Schlüsselargument verwendet, sofern sie nicht übergeben werden. In diesem Fall werden die Werte ausgewählt (siehe unten). Alle None-Objekte werden stillschweigend gelöscht, es sei denn, sie sind alle None. In diesem Fall wird ein ValueError ausgelöst
- Wir sehen dies normalerweise bei einer Liste von
Series
oder DataFrame
Objekten.
- Ich werde zeigen, dass
dict
das auch sehr nützlich sein kann.
- Generatoren können ebenfalls verwendet werden und können nützlich sein, wenn sie
map
wie in verwendet werdenmap(f, list_of_df)
Vorerst werden wir mit einer Liste von einigen der Stick DataFrame
und Series
Objekte oben definiert sind . Ich werde später zeigen, wie Wörterbücher genutzt werden können, um sehr nützliche MultiIndex
Ergebnisse zu erzielen.
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
Das zweite Argument ist das axis
Standardwert 0
:
Achse : {0 / 'Index', 1 / 'Spalten'}, Standard 0 Die Achse, entlang der verkettet werden soll.
Zwei DataFrame
s mit axis=0
(gestapelt)
Für Werte von 0
oder wollen index
wir sagen: "Entlang der Spalten ausrichten und zum Index hinzufügen".
Wie oben gezeigt, wo wir verwendet haben axis=0
, weil dies 0
der Standardwert ist und wir sehen, dass der Index von d2
den Index von erweitert, d1
obwohl es eine Überlappung des Werts gibt 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
Zwei DataFrame
s mit axis=1
(nebeneinander)
Für Werte 1
oder columns
wir wollen sagen: "Am Index ausrichten und zu den Spalten hinzufügen",
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
Wir können sehen, dass der resultierende Index die Vereinigung von Indizes ist und die resultierenden Spalten die Erweiterung von Spalten d1
um die Spalten von sind d2
.
Zwei (oder drei) Series
mit axis=0
(gestapelt)
Bei der Kombination pandas.Series
zusammen axis=0
, erhalten wir ein zurück pandas.Series
. Der Name des Ergebnisses Series
lautet, None
sofern nicht alle Series
zusammen den gleichen Namen haben. Achten Sie darauf, 'Name: A'
wann wir das Ergebnis ausdrucken Series
. Wenn es nicht vorhanden ist, können wir annehmen, dass der Series
Name ist 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
Zwei (oder drei) Series
mit axis=1
(nebeneinander)
Bei der Kombination von pandas.Series
zusammen axis=1
, es ist das name
Attribut , das wir zu beziehen , um einen Spaltennamen in den resultierenden abzuleiten 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
Gemischt Series
und DataFrame
mit axis=0
(gestapelt)
Wenn Sie eine Verkettung von a Series
und DataFrame
Along durchführen axis=0
, konvertieren wir alle Series
in einzelne Spalten DataFrame
.
Beachten Sie besonders, dass dies eine Verkettung ist axis=0
. Das bedeutet, dass der Index (die Zeilen) erweitert wird, während die Spalten ausgerichtet werden. In den folgenden Beispielen sehen wir, dass der Index zu [2, 3, 2, 3]
einem wahllosen Anhängen von Indizes wird. Die Spalten überlappen sich nur, wenn ich die Benennung der Series
Spalte mit dem Argument erzwinge 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
Sie können sehen, dass die Ergebnisse von pd.concat([s1, d1])
denen die gleichen sind, als ob ich die durchgeführt hätteto_frame
selbst durchgeführt hätte.
Ich kann jedoch den Namen der resultierenden Spalte mit einem Parameter an steuern to_frame
. Das Umbenennen von Series
mit der rename
Methode steuert nicht den Spaltennamen im Ergebnis 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
Gemischt Series
und DataFrame
mit axis=1
(nebeneinander)
Das ist ziemlich intuitiv. Series
Der Spaltenname verwendet standardmäßig eine Aufzählung solcher Series
Objekte, wenn ein name
Attribut nicht verfügbar ist.
| 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
Das dritte Argument join
beschreibt, ob die resultierende Zusammenführung eine äußere Zusammenführung (Standard) oder eine innere Zusammenführung sein soll.
join : {'inner', 'äußere'}, Standard 'äußere'
Umgang mit Indizes auf anderen Achsen.
Es stellt sich heraus, es gibt keine left
oder right
Option alspd.concat
mehr als nur zwei Objekte zum Zusammenführen verarbeitet werden können.
Im Fall von d1
und sehen d2
die Optionen folgendermaßen aus:
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
Das vierte Argument ist das, was es uns ermöglicht, unsere left
Verschmelzung und mehr zu tun .
join_axes : Liste der Indexobjekte
Spezifische Indizes, die für die anderen n - 1 Achsen verwendet werden sollen, anstatt die innere / äußere Mengenlogik auszuführen .
Linke Zusammenführung
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
Richtig zusammenführen
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
Wenn True, verwenden Sie die Indexwerte nicht entlang der Verkettungsachse. Die resultierende Achse wird mit 0, ..., n - 1 bezeichnet. Dies ist nützlich, wenn Sie Objekte verketten, bei denen die Verkettungsachse keine aussagekräftigen Indexinformationen enthält. Beachten Sie, dass die Indexwerte auf den anderen Achsen im Join weiterhin berücksichtigt werden.
Wie , wenn ich stapeln d1
oben auf d2
, wenn ich über die Indexwerte sich nicht, konnte ich sie zurücksetzen oder sie ignorieren.
| 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
Und bei der Verwendung von 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
Wir können eine Liste von Skalarwerten oder Tupeln übergeben, um dem entsprechenden MultiIndex Tupel- oder Skalarwerte zuzuweisen. Die Länge der übergebenen Liste muss mit der Anzahl der verketteten Elemente übereinstimmen.
Schlüssel : Sequenz, Standard Keine
Wenn mehrere Ebenen bestanden wurden, sollten Tupel enthalten. Erstellen Sie einen hierarchischen Index mit den übergebenen Schlüsseln als äußerste Ebene
axis=0
Beim Verketten von Series
Objekten entlang axis=0
(Erweitern des Index).
Diese Schlüssel werden zu einer neuen Anfangsebene eines MultiIndex
Objekts im Indexattribut.
# 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
Wir können jedoch mehr als skalare Werte im keys
Argument verwenden, um eine noch tiefere zu erstellen MultiIndex
. Hier übergeben wir tuples
der Länge 2 die vorangestellten zwei neuen Ebenen von a 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
Es ist ein bisschen anders, wenn man sich entlang von Spalten erstreckt. Bei der Verwendung axis=0
(siehe oben) keys
fungierten unsere MultiIndex
zusätzlich zum vorhandenen Index als Ebenen. Denn axis=1
wir beziehen uns auf eine Achse, die Series
Objekte nicht haben, nämlich das columns
Attribut.
Variationen von zwei
Series
mit
axis=1
Beachten Sie, dass die Benennung von s1
und s2
wichtig ist, solange keine übergeben keys
werden. Sie wird jedoch überschrieben, wenn sie übergeben keys
werden.
| | | 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
mit
Series
und
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
Zwei
DataFrame
mit
axis=1
Fügen Sie wie in den axis=0
Beispielen keys
Ebenen zu a hinzu MultiIndex
, diesmal jedoch zu dem im columns
Attribut gespeicherten Objekt .
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
und
DataFrame
mit
axis=1
Das ist schwierig. In diesem Fall kann ein Skalarschlüsselwert nicht als einzige Indexebene für das Series
Objekt fungieren, wenn es zu einer Spalte wird, während es gleichzeitig als erste Ebene von a MultiIndex
für das Objekt fungiert DataFrame
. Daher verwenden Pandas erneut das name
Attribut des Series
Objekts als Quelle für den Spaltennamen.
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
Einschränkungen
keys
und
MultiIndex
Schlussfolgerungen.
Pandas scheint nur Spaltennamen aus dem Series
Namen abzuleiten , füllt jedoch nicht die Lücken, wenn eine analoge Verkettung zwischen Datenrahmen mit einer anderen Anzahl von Spaltenebenen durchgeführt wird.
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
Verketten Sie dies dann mit einem anderen Datenrahmen mit nur einer Ebene im Spaltenobjekt, und Pandas weigert sich, Tupel des MultiIndex
Objekts zu erstellen und alle Datenrahmen so zu kombinieren, als ob eine einzelne Ebene von Objekten, Skalaren und Tupeln.
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
Pass a dict
statt alist
Wenn Sie ein Wörterbuch übergeben, pandas.concat
werden die Schlüssel aus dem Wörterbuch als keys
Parameter verwendet.
# 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
Dies wird in Verbindung mit dem keys
Argument verwendet. Wenn der levels
Standardwert von belassen wird None
, verwendet Pandas die eindeutigen Werte jeder Ebene des Ergebnisses MultiIndex
und verwendet diese als das im resultierenden index.levels
Attribut verwendete Objekt .
Ebenen : Liste der Sequenzen, Standard Keine
Spezifische Ebenen (eindeutige Werte), die zum Erstellen eines MultiIndex verwendet werden sollen. Andernfalls werden sie aus den Schlüsseln abgeleitet.
Wenn Pandas bereits darauf schließen, wie diese Ebenen aussehen sollten, welchen Vorteil gibt es dann, sie selbst festzulegen? Ich werde ein Beispiel zeigen und es Ihnen überlassen, sich andere Gründe auszudenken, warum dies nützlich sein könnte.
Beispiel
Gemäß der Dokumentation ist das levels
Argument eine Liste von Sequenzen. Dies bedeutet, dass wir eine andere pandas.Index
als eine dieser Sequenzen verwenden können.
Betrachten Sie den Datenrahmen df
, der die Verkettung von d1
, d2
und istd3
:
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
Die Ebenen des Spaltenobjekts sind:
print(df, *df.columns.levels, sep='\n')
Index(['First', 'Second', 'Fourth'], dtype='object')
Index(['A', 'B', 'C', 'D'], dtype='object')
Wenn wir sum
innerhalb eines verwendengroupby
wir:
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
Aber was wäre, wenn stattdessen ['First', 'Second', 'Fourth']
keine anderen Kategorien mit dem Namen Third
und fehlen würden Fifth
? Und ich wollte, dass sie in die Ergebnisse von a aufgenommen werdengroupby
Aggregation ? Wir können das tun, wenn wir eine hätten pandas.CategoricalIndex
. Und das können wir mit dem levels
Argument vorab festlegen .
Definieren wir stattdessen Folgendes df
:
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
Die erste Ebene des Spaltenobjekts lautet jedoch:
df.columns.levels[0]
CategoricalIndex(
['First', 'Second', 'Third', 'Fourth', 'Fifth'],
categories=['First', 'Second', 'Third', 'Fourth', 'Fifth'],
ordered=True, dtype='category')
Und unsere groupby
Zusammenfassung sieht aus wie:
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
Dies wird verwendet, um die Ebenen eines Ergebnisses zu benennen MultiIndex
. Die Länge der names
Liste sollte mit der Anzahl der Ebenen in der resultierenden übereinstimmenMultiIndex
.
Namen : Liste, Standard Keine
Namen für die Ebenen im resultierenden hierarchischen Index
# 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
Selbsterklärende Dokumentation
verify_integrity : boolean, default False
Überprüfen Sie, ob die neue verkettete Achse Duplikate enthält. Dies kann im Verhältnis zur tatsächlichen Datenverkettung sehr teuer sein.
Da der resultierende Index verkettet d1
und d2
nicht eindeutig ist, würde die Integritätsprüfung fehlschlagen.
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
Und
pd.concat([d1, d2], verify_integrity=True)
> ValueError: Indizes haben überlappende Werte: [2]
pd.concat(..., levels=[lvl]).groupby(axis=1, level=0).sum()
führt zu einem anderen Ergebnis alspd.concat(..., levels=[cats]).groupby(axis=1, level=0).sum()
. Weißt du, warum? Die Dokumente sagen nur,levels
sollte eine Liste von Sequenzen sein.Passing a dict instead of a list
braucht ein Beispiel mit einem Diktat, keine Liste.dict
Beispiel behoben, danke. Der Grund dafür ist, dass dieslvl
ein kategorialer Index ist undcats
nur eine Liste. Bei der Gruppierung nach einem Kategorietyp werden die fehlenden Kategorien gegebenenfalls mit Nullen und Nullen gefüllt. Siehe dies