[PYTHON] Pandas Benutzerhandbuch "Multi-Index / Advanced Index" (offizielles Dokument Japanische Übersetzung)

Dieser Artikel ist eine Teilübersetzung der offiziellen Pandas-Dokumentation Benutzerhandbuch - MultiIndex / Advanced Indexing. Es ist eine Modifikation eines unnatürlichen Satzes. Die neueste Release-Version von Pandas ist zum Zeitpunkt des Schreibens dieses Artikels "0.25.3", aber der Text dieses Artikels basiert unter Berücksichtigung der Zukunft auf dem Dokument der Entwicklungsversion "1.0.0".

Wenn Sie falsche Übersetzungen, alternative Übersetzungen, Fragen usw. haben, verwenden Sie bitte den Kommentarbereich oder bearbeiten Sie die Anfrage.

Multi-Index / erweiterter Index

In diesem Kapitel wird die Indizierung mit Multi-Index (# Hierarchischer Index (Multi-Index)) und anderen erweiterten Indizierungsfunktionen (#Andere erweiterte Indizierungsfunktionen) beschrieben.

Eine grundlegende Dokumentation zur Indizierung finden Sie unter Indizieren und Auswählen von Daten (https://qiita.com/nkay/items/d322ed9d9a14bdbf14cb).

: Warnung: ** Warnung ** Ob der Zuweisungsvorgang eine Kopie oder eine Referenz zurückgibt, hängt vom Kontext ab. Dies wird als verkettete Zuordnung bezeichnet und sollte vermieden werden. Siehe [Zurückgeben einer Ansicht oder Kopie](https://qiita.com/nkay/items/d322ed9d9a14bdbf14cb#Returning einer Ansicht oder Kopie).

Weitere Informationen finden Sie unter Kochbuch.

Hierarchischer Index (Multi-Index)

Hierarchische und mehrstufige Indizes sind sehr nützlich für die erweiterte Datenanalyse und -manipulation, insbesondere beim Umgang mit hochdimensionalen Daten. Im Wesentlichen können Sie eine beliebige Anzahl von Dimensionen in einer niedrigdimensionalen Datenstruktur wie "Serie" (1d) oder "Datenrahmen" (2d) speichern und bearbeiten.

Dieser Abschnitt zeigt, was ein "hierarchischer" Index bedeutet und wie er in alle oben und in den vorherigen Kapiteln beschriebenen Pandas-Indexierungsfunktionen integriert wird. Später Gruppieren (https://pandas.pydata.org/pandas-docs/stable/user_guide/groupby.html#groupby) und Schwenken und Umformen von Daten (https://pandas.pydata.org/) Wenn wir über pandas-docs / stabile / user_guide / reshaping.html # reshaping) sprechen, stellen wir Ihnen eine wichtige Anwendung vor, um zu erklären, wie Sie damit Ihre Daten für die Analyse strukturieren können.

Weitere Informationen finden Sie im Kochbuch.

_ In Version 0.24.0 geändert _: MultiIndex.labels wurde in MultiIndex.codes geändert und MultiIndex.set_labels wurde in MultiIndex.set_codes geändert.

Erstellen eines MultiIndex-Objekts (hierarchischer Index)

In Pandas-Objekten wird das Objekt "Index" häufig zum Speichern von Achsenbeschriftungen verwendet, das Objekt "MultiIndex" ist jedoch eine hierarchische Version davon. Sie können sich "MultiIndex" als eine Reihe von Taples vorstellen, bei denen jeder Tapple ein Unikat ist. MultiIndex verwendet eine Liste von Arrays (mit MultiIndex.from_arrays ()), ein Array von Taples (mitMultiIndex.from_tuples ()) und (MultiIndex.from_product (). Es kann aus einem direkten Produkt von Iterables, "DataFrame" (unter Verwendung von "MultiIndex.from_frame ()") erstellt werden. Der Konstruktor "Index" versucht, "MultiIndex" zurückzugeben, wenn eine Liste von Taples übergeben wird. Im Folgenden finden Sie verschiedene Möglichkeiten zum Initialisieren von MultiIndex.

In [1]: arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
   ...:           ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
   ...:

In [2]: tuples = list(zip(*arrays))

In [3]: tuples
Out[3]:
[('bar', 'one'),
 ('bar', 'two'),
 ('baz', 'one'),
 ('baz', 'two'),
 ('foo', 'one'),
 ('foo', 'two'),
 ('qux', 'one'),
 ('qux', 'two')]

In [4]: index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])

In [5]: index
Out[5]:
MultiIndex([('bar', 'one'),
            ('bar', 'two'),
            ('baz', 'one'),
            ('baz', 'two'),
            ('foo', 'one'),
            ('foo', 'two'),
            ('qux', 'one'),
            ('qux', 'two')],
           names=['first', 'second'])

In [6]: s = pd.Series(np.random.randn(8), index=index)

In [7]: s
Out[7]:
first  second
bar    one       0.469112
       two      -0.282863
baz    one      -1.509059
       two      -1.135632
foo    one       1.212112
       two      -0.173215
qux    one       0.119209
       two      -1.044236
dtype: float64

Wenn Sie alle Kombinationen (direkte Produkte) der beiden iterierbaren Elemente möchten, können Sie bequem die Methode "MultiIndex.from_product ()" verwenden.

In [8]: iterables = [['bar', 'baz', 'foo', 'qux'], ['one', 'two']]

In [9]: pd.MultiIndex.from_product(iterables, names=['first', 'second'])
Out[9]:
MultiIndex([('bar', 'one'),
            ('bar', 'two'),
            ('baz', 'one'),
            ('baz', 'two'),
            ('foo', 'one'),
            ('foo', 'two'),
            ('qux', 'one'),
            ('qux', 'two')],
           names=['first', 'second'])

Sie können auch die Methode "MultiIndex.from_frame ()" verwenden, um einen "MultiIndex" direkt aus dem "DataFrame" zu erstellen. Dies ist eine Methode, die "MultiIndex.to_frame ()" ergänzt.

_ Ab Version 0.24.0 _

In [10]: df = pd.DataFrame([['bar', 'one'], ['bar', 'two'],
   ....:                    ['foo', 'one'], ['foo', 'two']],
   ....:                   columns=['first', 'second'])
   ....:

In [11]: pd.MultiIndex.from_frame(df)
Out[11]:
MultiIndex([('bar', 'one'),
            ('bar', 'two'),
            ('foo', 'one'),
            ('foo', 'two')],
           names=['first', 'second'])

Sie können auch automatisch einen "MultiIndex" erstellen, indem Sie die Liste der Arrays direkt an die "Serie" oder den "DataFrame" übergeben, wie unten gezeigt.

In [12]: arrays = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']),
   ....:           np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'])]
   ....:

In [13]: s = pd.Series(np.random.randn(8), index=arrays)

In [14]: s
Out[14]:
bar  one   -0.861849
     two   -2.104569
baz  one   -0.494929
     two    1.071804
foo  one    0.721555
     two   -0.706771
qux  one   -1.039575
     two    0.271860
dtype: float64

In [15]: df = pd.DataFrame(np.random.randn(8, 4), index=arrays)

In [16]: df
Out[16]:
                0         1         2         3
bar one -0.424972  0.567020  0.276232 -1.087401
    two -0.673690  0.113648 -1.478427  0.524988
baz one  0.404705  0.577046 -1.715002 -1.039268
    two -0.370647 -1.157892 -1.344312  0.844885
foo one  1.075770 -0.109050  1.643563 -1.469388
    two  0.357021 -0.674600 -1.776904 -0.968914
qux one -1.294524  0.413738  0.276662 -0.472035
    two -0.013960 -0.362543 -0.006154 -0.923061

Alle "MultiIndex" -Konstruktoren verwenden ein "names" -Argument, in dem die eigenen Zeichenfolgennamen (Labels) der Ebene gespeichert sind. Wenn kein Name angegeben ist, wird "Keine" zugewiesen.

In [17]: df.index.names
Out[17]: FrozenList([None, None])

Dieser Index kann auf der Achse in einer beliebigen Richtung des Pandas-Objekts festgelegt werden, und die Anzahl der ** Ebenen ** des Index ist beliebig.

In [18]: df = pd.DataFrame(np.random.randn(3, 8), index=['A', 'B', 'C'], columns=index)

In [19]: df
Out[19]:
first        bar                 baz                 foo                 qux
second       one       two       one       two       one       two       one       two
A       0.895717  0.805244 -1.206412  2.565646  1.431256  1.340309 -1.170299 -0.226169
B       0.410835  0.813850  0.132003 -0.827317 -0.076467 -1.187678  1.130127 -1.436737
C      -1.413681  1.607920  1.024180  0.569605  0.875906 -2.211372  0.974466 -2.006747

In [20]: pd.DataFrame(np.random.randn(6, 6), index=index[:6], columns=index[:6])
Out[20]:
first              bar                 baz                 foo
second             one       two       one       two       one       two
first second
bar   one    -0.410001 -0.078638  0.545952 -1.219217 -1.226825  0.769804
      two    -1.281247 -0.727707 -0.121306 -0.097883  0.695775  0.341734
baz   one     0.959726 -1.110336 -0.619976  0.149748 -0.732339  0.687738
      two     0.176444  0.403310 -0.154951  0.301624 -2.179861 -1.369849
foo   one    -0.954208  1.462696 -1.743161 -0.826591 -0.345352  1.314232
      two     0.690579  0.995761  2.396780  0.014871  3.357427 -0.317441

Wir haben einen übergeordneten Index "gespart", damit die Konsolenausgabe besser sichtbar ist. Sie können steuern, wie der Index angezeigt wird, indem Sie die Option multi_sparse von pandas.set_options () verwenden.

In [21]: with pd.option_context('display.multi_sparse', False):
   ....:     df
   ....:

Es sei daran erinnert, dass es in Ordnung ist, Taples als einzelnes, unteilbares Etikett zu verwenden.

In [22]: pd.Series(np.random.randn(8), index=tuples)
Out[22]:
(bar, one)   -1.236269
(bar, two)    0.896171
(baz, one)   -0.487602
(baz, two)   -0.082240
(foo, one)   -2.182937
(foo, two)    0.380396
(qux, one)    0.084844
(qux, two)    0.432390
dtype: float64

Der Grund, warum "MultiIndex" wichtig ist, besteht darin, dass Sie "MultiIndex" verwenden können, um Gruppierungs-, Auswahl- und Formänderungsvorgänge durchzuführen, wie im folgenden und den folgenden Kapiteln erläutert. Wie Sie in einem späteren Abschnitt sehen werden, können Sie mit hierarchisch indizierten Daten arbeiten, ohne den "MultiIndex" explizit selbst erstellen zu müssen. Wenn Sie jedoch Daten aus einer Datei laden, können Sie bei der Vorbereitung des Datasets Ihren eigenen "MultiIndex" generieren.

Level-Labels neu erstellen

get_level_values () Die Methode gilt für jede bestimmte Ebene Gibt einen Vektor von Positionsbezeichnungen zurück.

In [23]: index.get_level_values(0)
Out[23]: Index(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'], dtype='object', name='first')

In [24]: index.get_level_values('second')
Out[24]: Index(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'], dtype='object', name='second')

Grundlegende Indizierung von Achsen mit MultiIndex

Eines der Hauptmerkmale eines hierarchischen Index ist die Möglichkeit, Daten anhand einer "partiellen" Bezeichnung auszuwählen, die eine Untergruppe in den Daten identifiziert. ** Teil ** Auswahl "löscht" die Ebene des resultierenden hierarchischen Index genauso wie die Auswahl einer Spalte in einem regulären DataFrame.

In [25]: df['bar']
Out[25]:
second       one       two
A       0.895717  0.805244
B       0.410835  0.813850
C      -1.413681  1.607920

In [26]: df['bar', 'one']
Out[26]:
A    0.895717
B    0.410835
C   -1.413681
Name: (bar, one), dtype: float64

In [27]: df['bar']['one']
Out[27]:
A    0.895717
B    0.410835
C   -1.413681
Name: one, dtype: float64

In [28]: s['qux']
Out[28]:
one   -1.039575
two    0.271860
dtype: float64

Informationen zur Auswahl auf einer tieferen Ebene finden Sie unter Abschnitte mit hierarchischen Indizes.

Level Definition

MultiIndex wurde definiert, auch wenn es nicht tatsächlich verwendet wurde Enthält Indizes für alle Ebenen. Möglicherweise bemerken Sie dies, wenn Sie den Index aufteilen. Zum Beispiel

In [29]: df.columns.levels  # original MultiIndex
Out[29]: FrozenList([['bar', 'baz', 'foo', 'qux'], ['one', 'two']])

In [30]: df[['foo','qux']].columns.levels  # sliced
Out[30]: FrozenList([['bar', 'baz', 'foo', 'qux'], ['one', 'two']])

Dies geschieht, um Neuberechnungen des Pegels zu vermeiden und die Slice-Leistung zu verbessern. Wenn Sie nur die verwendeten Ebenen anzeigen möchten, get_level_values (). Sie können die Methode MultiIndex.get_level_values verwenden.

In [31]: df[['foo', 'qux']].columns.to_numpy()
Out[31]:
array([('foo', 'one'), ('foo', 'two'), ('qux', 'one'), ('qux', 'two')],
      dtype=object)

# for a specific level
In [32]: df[['foo', 'qux']].columns.get_level_values(0)
Out[32]: Index(['foo', 'foo', 'qux', 'qux'], dtype='object', name='first')

Um "MultiIndex" nur mit Nutzungsstufen neu zu erstellen, [remove_unused_levels ()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.MultiIndex.remove_unused_levels.html# Sie können die Methode pandas.MultiIndex.remove_unused_levels verwenden.

In [33]: new_mi = df[['foo', 'qux']].columns.remove_unused_levels()

In [34]: new_mi.levels
Out[34]: FrozenList([['foo', 'qux'], ['one', 'two']])

Datenausrichtung und Verwendung von "Reindex"

Operationen zwischen Objekten mit unterschiedlichen Indizes, die "MultiIndex" auf der Achse haben, funktionieren wie erwartet. Die Datenausrichtung funktioniert wie ein Tapple-Index.

In [35]: s + s[:-2]
Out[35]:
bar  one   -1.723698
     two   -4.209138
baz  one   -0.989859
     two    2.143608
foo  one    1.443110
     two   -1.413542
qux  one         NaN
     two         NaN
dtype: float64

In [36]: s + s[::2]
Out[36]:
bar  one   -1.723698
     two         NaN
baz  one   -0.989859
     two         NaN
foo  one    1.443110
     two         NaN
qux  one   -2.079150
     two         NaN
dtype: float64

[Reindex ()] von Series / DataFrames (https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.reindex.html#pandas.DataFrame.reindex) Die Methode kann auch einen anderen "MultiIndex" oder eine Liste oder ein Array von Tupeln empfangen.

In [37]: s.reindex(index[:3])
Out[37]:
first  second
bar    one      -0.861849
       two      -2.104569
baz    one      -0.494929
dtype: float64

In [38]: s.reindex([('foo', 'two'), ('bar', 'one'), ('qux', 'one'), ('baz', 'one')])
Out[38]:
foo  two   -0.706771
bar  one   -0.861849
qux  one   -1.039575
baz  one   -0.494929
dtype: float64

Erweiterte Indizierung mit hierarchischen Indizes

Es ist syntaktisch etwas schwierig, MultiIndex dazu zu bringen, eine erweiterte Indizierung mit .loc durchzuführen, aber wir haben alle Anstrengungen unternommen, um dies zu erreichen. Im Allgemeinen haben MultiIndex-Schlüssel die Form von Taples. Das Folgende funktioniert beispielsweise wie erwartet.

In [39]: df = df.T

In [40]: df
Out[40]:
                     A         B         C
first second
bar   one     0.895717  0.410835 -1.413681
      two     0.805244  0.813850  1.607920
baz   one    -1.206412  0.132003  1.024180
      two     2.565646 -0.827317  0.569605
foo   one     1.431256 -0.076467  0.875906
      two     1.340309 -1.187678 -2.211372
qux   one    -1.170299  1.130127  0.974466
      two    -0.226169 -1.436737 -2.006747

In [41]: df.loc[('bar', 'two')]
Out[41]:
A    0.805244
B    0.813850
C    1.607920
Name: (bar, two), dtype: float64

In diesem Beispiel funktioniert auch "df.loc [" bar "," two "]". Beachten Sie jedoch, dass diese Abkürzung im Allgemeinen irreführend sein kann.

Wenn Sie ".loc" verwenden, um aus einer bestimmten Spalte zu indizieren, müssen Sie den Taple wie folgt verwenden:

In [42]: df.loc[('bar', 'two'), 'A']
Out[42]: 0.8052440253863785

Wenn Sie nur das erste Element des Taple übergeben, müssen Sie nicht alle Ebenen von MultiIndex angeben. Beispielsweise können Sie den "Teil" -Index verwenden, um alle Elemente mit "Balken" in der ersten Ebene wie folgt abzurufen:

df.loc['bar']

Dies ist eine Abkürzung für die redundantere Notation "df.loc [('bar',),]" (in diesem Beispiel auch äquivalent zu "df.loc ['bar',]").

Das "Partial" Slice funktioniert auch sehr gut.

In [43]: df.loc['baz':'foo']
Out[43]:
                     A         B         C
first second
baz   one    -1.206412  0.132003  1.024180
      two     2.565646 -0.827317  0.569605
foo   one     1.431256 -0.076467  0.875906
      two     1.340309 -1.187678 -2.211372

Sie können nach dem "Wertebereich" schneiden, indem Sie ein Stück des Taples übergeben.

In [44]: df.loc[('baz', 'two'):('qux', 'one')]
Out[44]:
                     A         B         C
first second
baz   two     2.565646 -0.827317  0.569605
foo   one     1.431256 -0.076467  0.875906
      two     1.340309 -1.187678 -2.211372
qux   one    -1.170299  1.130127  0.974466

In [45]: df.loc[('baz', 'two'):'foo']
Out[45]:
                     A         B         C
first second
baz   two     2.565646 -0.827317  0.569605
foo   one     1.431256 -0.076467  0.875906
      two     1.340309 -1.187678 -2.211372

Wie bei der Neuindizierung können Sie auch eine Liste mit Beschriftungen oder Tupeln übergeben.

In [46]: df.loc[[('bar', 'two'), ('qux', 'one')]]
Out[46]:
                     A         B         C
first second
bar   two     0.805244  0.813850  1.607920
qux   one    -1.170299  1.130127  0.974466

: ballot_box_with_check: ** Hinweis ** Beachten Sie, dass Tapples und Listen in Pandas bei der Indizierung nicht gleich behandelt werden. Ein Taple wird als ein einzelner mehrstufiger Schlüssel interpretiert, eine Liste zeigt jedoch auf mehrere Schlüssel. Mit anderen Worten, der Taple bewegt sich horizontal (überquert die Ebene) und die Liste bewegt sich vertikal (scannt die Ebene).

Wichtig ist, dass eine Liste von Taples mehrere vollständige "MultiIndex" -Schlüssel abruft, aber ein Tapple einer Liste verweist auf einen Wert in einer Ebene.

In [47]: s = pd.Series([1, 2, 3, 4, 5, 6],
   ....:               index=pd.MultiIndex.from_product([["A", "B"], ["c", "d", "e"]]))
   ....:

In [48]: s.loc[[("A", "c"), ("B", "d")]]  # list of tuples
Out[48]:
A  c    1
B  d    5
dtype: int64

In [49]: s.loc[(["A", "B"], ["c", "d"])]  # tuple of lists
Out[49]:
A  c    1
   d    2
B  c    4
   d    5
dtype: int64

Verwendung eines Allesschneiders

Sie können "MultiIndex" in Scheiben schneiden, indem Sie mehrere Indexer bereitstellen.

Verwenden Sie auf die gleiche Weise eine der Auswahlmöglichkeiten für Slice-Label-Liste, Label und Boolesches Array, die Sie unter Select by Label (https://qiita.com/nkay/items/d322ed9d9a14bdbf14cb#Select by Label) sehen. Ich kann.

Sie können "Slice (None)" verwenden, um alle Elemente auf * dieser * Ebene auszuwählen. Es ist nicht erforderlich, alle * tieferen * Ebenen anzugeben. Sie werden durch "Slice (None)" impliziert.

Wie bei den anderen handelt es sich hierbei um eine Etikettenindizierung, die ** beide Seiten ** des Slicers umfasst.

: Warnung: ** Warnung ** Geben Sie in .loc alle Achsen an (** Index ** und ** Spalten **). Es gibt einige mehrdeutige Fälle, in denen der übergebene Indexer als Index auf * beiden * Achsen und nicht als "MultiIndex" einer Zeile falsch interpretiert werden kann. Schreiben Sie wie folgt.

df.loc[(slice('A1', 'A3'), ...), :]             # noqa: E999

Schreiben Sie nicht wie folgt.

df.loc[(slice('A1', 'A3'), ...)]                # noqa: E999
In [50]: def mklbl(prefix, n):
   ....:     return ["%s%s" % (prefix, i) for i in range(n)]
   ....:

In [51]: miindex = pd.MultiIndex.from_product([mklbl('A', 4),
   ....:                                       mklbl('B', 2),
   ....:                                       mklbl('C', 4),
   ....:                                       mklbl('D', 2)])
   ....:

In [52]: micolumns = pd.MultiIndex.from_tuples([('a', 'foo'), ('a', 'bar'),
   ....:                                        ('b', 'foo'), ('b', 'bah')],
   ....:                                       names=['lvl0', 'lvl1'])
   ....:

In [53]: dfmi = pd.DataFrame(np.arange(len(miindex) * len(micolumns))
   ....:                       .reshape((len(miindex), len(micolumns))),
   ....:                     index=miindex,
   ....:                     columns=micolumns).sort_index().sort_index(axis=1)
   ....:

In [54]: dfmi
Out[54]:
lvl0           a         b
lvl1         bar  foo  bah  foo
A0 B0 C0 D0    1    0    3    2
         D1    5    4    7    6
      C1 D0    9    8   11   10
         D1   13   12   15   14
      C2 D0   17   16   19   18
...          ...  ...  ...  ...
A3 B1 C1 D1  237  236  239  238
      C2 D0  241  240  243  242
         D1  245  244  247  246
      C3 D0  249  248  251  250
         D1  253  252  255  254

[64 rows x 4 columns]

Grundlegendes Multi-Index-Slicing mit Slice-Listenbeschriftungen.

In [55]: dfmi.loc[(slice('A1', 'A3'), slice(None), ['C1', 'C3']), :]
Out[55]:
lvl0           a         b
lvl1         bar  foo  bah  foo
A1 B0 C1 D0   73   72   75   74
         D1   77   76   79   78
      C3 D0   89   88   91   90
         D1   93   92   95   94
   B1 C1 D0  105  104  107  106
...          ...  ...  ...  ...
A3 B0 C3 D1  221  220  223  222
   B1 C1 D0  233  232  235  234
         D1  237  236  239  238
      C3 D0  249  248  251  250
         D1  253  252  255  254

[24 rows x 4 columns]

In slice (None) using Pandas.IndexSlice Sie können eine natürlichere Syntax verwenden als :.

In [56]: idx = pd.IndexSlice

In [57]: dfmi.loc[idx[:, :, ['C1', 'C3']], idx[:, 'foo']]
Out[57]:
lvl0           a    b
lvl1         foo  foo
A0 B0 C1 D0    8   10
         D1   12   14
      C3 D0   24   26
         D1   28   30
   B1 C1 D0   40   42
...          ...  ...
A3 B0 C3 D1  220  222
   B1 C1 D0  232  234
         D1  236  238
      C3 D0  248  250
         D1  252  254

[32 rows x 2 columns]

Mit dieser Methode können Sie sehr komplexe Auswahlen auf mehreren Achsen gleichzeitig treffen.

In [58]: dfmi.loc['A1', (slice(None), 'foo')]
Out[58]:
lvl0        a    b
lvl1      foo  foo
B0 C0 D0   64   66
      D1   68   70
   C1 D0   72   74
      D1   76   78
   C2 D0   80   82
...       ...  ...
B1 C1 D1  108  110
   C2 D0  112  114
      D1  116  118
   C3 D0  120  122
      D1  124  126

[16 rows x 2 columns]

In [59]: dfmi.loc[idx[:, :, ['C1', 'C3']], idx[:, 'foo']]
Out[59]:
lvl0           a    b
lvl1         foo  foo
A0 B0 C1 D0    8   10
         D1   12   14
      C3 D0   24   26
         D1   28   30
   B1 C1 D0   40   42
...          ...  ...
A3 B0 C3 D1  220  222
   B1 C1 D0  232  234
         D1  236  238
      C3 D0  248  250
         D1  252  254

[32 rows x 2 columns]

Sie können den Booleschen Indexer verwenden, um eine Auswahl für * Werte * bereitzustellen.

In [60]: mask = dfmi[('a', 'foo')] > 200

In [61]: dfmi.loc[idx[mask, :, ['C1', 'C3']], idx[:, 'foo']]
Out[61]:
lvl0           a    b
lvl1         foo  foo
A3 B0 C1 D1  204  206
      C3 D0  216  218
         D1  220  222
   B1 C1 D0  232  234
         D1  236  238
      C3 D0  248  250
         D1  252  254

Sie können auch das Argument "Achse" in ".loc" angeben, um einen Slicer zu interpretieren, der auf einer einzelnen Achse übergeben wird.

In [62]: dfmi.loc(axis=0)[:, :, ['C1', 'C3']]
Out[62]:
lvl0           a         b
lvl1         bar  foo  bah  foo
A0 B0 C1 D0    9    8   11   10
         D1   13   12   15   14
      C3 D0   25   24   27   26
         D1   29   28   31   30
   B1 C1 D0   41   40   43   42
...          ...  ...  ...  ...
A3 B0 C3 D1  221  220  223  222
   B1 C1 D0  233  232  235  234
         D1  237  236  239  238
      C3 D0  249  248  251  250
         D1  253  252  255  254

[32 rows x 4 columns]

Darüber hinaus können Sie Werte mit den folgenden Methoden * zuweisen *:

In [63]: df2 = dfmi.copy()

In [64]: df2.loc(axis=0)[:, :, ['C1', 'C3']] = -10

In [65]: df2
Out[65]:
lvl0           a         b
lvl1         bar  foo  bah  foo
A0 B0 C0 D0    1    0    3    2
         D1    5    4    7    6
      C1 D0  -10  -10  -10  -10
         D1  -10  -10  -10  -10
      C2 D0   17   16   19   18
...          ...  ...  ...  ...
A3 B1 C1 D1  -10  -10  -10  -10
      C2 D0  241  240  243  242
         D1  245  244  247  246
      C3 D0  -10  -10  -10  -10
         D1  -10  -10  -10  -10

[64 rows x 4 columns]

Sie können auch die rechte Seite des ausrichtbaren Objekts verwenden.

In [66]: df2 = dfmi.copy()

In [67]: df2.loc[idx[:, :, ['C1', 'C3']], :] = df2 * 1000

In [68]: df2
Out[68]:
lvl0              a               b
lvl1            bar     foo     bah     foo
A0 B0 C0 D0       1       0       3       2
         D1       5       4       7       6
      C1 D0    9000    8000   11000   10000
         D1   13000   12000   15000   14000
      C2 D0      17      16      19      18
...             ...     ...     ...     ...
A3 B1 C1 D1  237000  236000  239000  238000
      C2 D0     241     240     243     242
         D1     245     244     247     246
      C3 D0  249000  248000  251000  250000
         D1  253000  252000  255000  254000

[64 rows x 4 columns]

Cross-section

Die xs () -Methode von DataFrame verwendet auch ein Ebenenargument, um die Auswahl von Daten auf einer bestimmten Ebene von MultiIndex zu vereinfachen.

In [69]: df
Out[69]:
                     A         B         C
first second
bar   one     0.895717  0.410835 -1.413681
      two     0.805244  0.813850  1.607920
baz   one    -1.206412  0.132003  1.024180
      two     2.565646 -0.827317  0.569605
foo   one     1.431256 -0.076467  0.875906
      two     1.340309 -1.187678 -2.211372
qux   one    -1.170299  1.130127  0.974466
      two    -0.226169 -1.436737 -2.006747

In [70]: df.xs('one', level='second')
Out[70]:
              A         B         C
first
bar    0.895717  0.410835 -1.413681
baz   -1.206412  0.132003  1.024180
foo    1.431256 -0.076467  0.875906
qux   -1.170299  1.130127  0.974466
#Verwendung von Scheiben
In [71]: df.loc[(slice(None), 'one'), :]
Out[71]:
                     A         B         C
first second
bar   one     0.895717  0.410835 -1.413681
baz   one    -1.206412  0.132003  1.024180
foo   one     1.431256 -0.076467  0.875906
qux   one    -1.170299  1.130127  0.974466

Sie können auch Spalten mit "xs" auswählen, indem Sie das Axis-Argument angeben.

In [72]: df = df.T

In [73]: df.xs('one', level='second', axis=1)
Out[73]:
first       bar       baz       foo       qux
A      0.895717 -1.206412  1.431256 -1.170299
B      0.410835  0.132003 -0.076467  1.130127
C     -1.413681  1.024180  0.875906  0.974466
#Verwendung von Scheiben
In [74]: df.loc[:, (slice(None), 'one')]
Out[74]:
first        bar       baz       foo       qux
second       one       one       one       one
A       0.895717 -1.206412  1.431256 -1.170299
B       0.410835  0.132003 -0.076467  1.130127
C      -1.413681  1.024180  0.875906  0.974466

Mit xs können Sie auch mit mehreren Tasten auswählen.

In [75]: df.xs(('one', 'bar'), level=('second', 'first'), axis=1)
Out[75]:
first        bar
second       one
A       0.895717
B       0.410835
C      -1.413681
#Verwendung von Scheiben
In [76]: df.loc[:, ('bar', 'one')]
Out[76]:
A    0.895717
B    0.410835
C   -1.413681
Name: (bar, one), dtype: float64

Sie können das ausgewählte Level beibehalten, indem Sie drop_level = False an xs übergeben.

In [77]: df.xs('one', level='second', axis=1, drop_level=False)
Out[77]:
first        bar       baz       foo       qux
second       one       one       one       one
A       0.895717 -1.206412  1.431256 -1.170299
B       0.410835  0.132003 -0.076467  1.130127
C      -1.413681  1.024180  0.875906  0.974466

Vergleichen Sie das obige Ergebnis mit dem Fall von drop_level = True (Standardwert).

In [78]: df.xs('one', level='second', axis=1, drop_level=True)
Out[78]:
first       bar       baz       foo       qux
A      0.895717 -1.206412  1.431256 -1.170299
B      0.410835  0.132003 -0.076467  1.130127
C     -1.413681  1.024180  0.875906  0.974466

Erweiterte Neuindizierung und Ausrichtung

Das Pandas-Objekt reindex () und align ( align (align) ) Wenn Sie das Argument level in der Methode verwenden, die gesamte Ebene Nützlich für die Übertragung von Werten an. Zum Beispiel:

In [79]: midx = pd.MultiIndex(levels=[['zero', 'one'], ['x', 'y']],
   ....:                      codes=[[1, 1, 0, 0], [1, 0, 1, 0]])
   ....:

In [80]: df = pd.DataFrame(np.random.randn(4, 2), index=midx)

In [81]: df
Out[81]:
               0         1
one  y  1.519970 -0.493662
     x  0.600178  0.274230
zero y  0.132885 -0.023688
     x  2.410179  1.450520

In [82]: df2 = df.mean(level=0)

In [83]: df2
Out[83]:
             0         1
one   1.060074 -0.109716
zero  1.271532  0.713416

In [84]: df2.reindex(df.index, level=0)
Out[84]:
               0         1
one  y  1.060074 -0.109716
     x  1.060074 -0.109716
zero y  1.271532  0.713416
     x  1.271532  0.713416

#Ausrichtung
In [85]: df_aligned, df2_aligned = df.align(df2, level=0)

In [86]: df_aligned
Out[86]:
               0         1
one  y  1.519970 -0.493662
     x  0.600178  0.274230
zero y  0.132885 -0.023688
     x  2.410179  1.450520

In [87]: df2_aligned
Out[87]:
               0         1
one  y  1.060074 -0.109716
     x  1.060074 -0.109716
zero y  1.271532  0.713416
     x  1.271532  0.713416

Level Order Exchange durch Swaplevel

Die Methode swaplevel () besteht aus zwei Ebenen Kann ersetzt werden.

In [88]: df[:5]
Out[88]:
               0         1
one  y  1.519970 -0.493662
     x  0.600178  0.274230
zero y  0.132885 -0.023688
     x  2.410179  1.450520

In [89]: df[:5].swaplevel(0, 1, axis=0)
Out[89]:
               0         1
y one   1.519970 -0.493662
x one   0.600178  0.274230
y zero  0.132885 -0.023688
x zero  2.410179  1.450520

Sortieren von Ebenen nach "reorder_levels"

Die Methode reorder_levels () ist die Methode swaplevel. Verallgemeinern Sie, damit Sie die Ebene eines hierarchischen Index in einem Schritt ersetzen können.

In [90]: df[:5].reorder_levels([1, 0], axis=0)
Out[90]:
               0         1
y one   1.519970 -0.493662
x one   0.600178  0.274230
y zero  0.132885 -0.023688
x zero  2.410179  1.450520

Benennen Sie "Index" oder "MultiIndex" um

[Rename ()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.rename.html] wird normalerweise zum Umbenennen von Spalten in DataFrame verwendet Die Methode # pandas.DataFrame.rename) kann auch das Label "MultiIndex" umbenennen. Das Argument "Spalten" von "Umbenennen" kann ein Wörterbuch sein, das nur die Spalten enthält, die Sie umbenennen möchten.

In [91]: df.rename(columns={0: "col0", 1: "col1"})
Out[91]:
            col0      col1
one  y  1.519970 -0.493662
     x  0.600178  0.274230
zero y  0.132885 -0.023688
     x  2.410179  1.450520

Diese Methode kann auch verwendet werden, um eine bestimmte Bezeichnung im Hauptindex des "DataFrame" umzubenennen.

In [92]: df.rename(index={"one": "two", "y": "z"})
Out[92]:
               0         1
two  z  1.519970 -0.493662
     x  0.600178  0.274230
zero z  0.132885 -0.023688
     x  2.410179  1.450520

rename_axis () Die Methode lautet Index oder MultiIndex umbenennen. Insbesondere können Sie einen Ebenennamen für den "MultiIndex" angeben, was später nützlich ist, wenn Sie "reset_index ()" verwenden, um den Wert vom MultiIndex in eine reguläre Spalte zu verschieben.

In [93]: df.rename_axis(index=['abc', 'def'])
Out[93]:
                 0         1
abc  def
one  y    1.519970 -0.493662
     x    0.600178  0.274230
zero y    0.132885 -0.023688
     x    2.410179  1.450520

Beachten Sie, dass die Spalten im "DataFrame" Indizes sind. Wenn Sie also "rename_axis" mit dem Argument "column" verwenden, wird der Index umbenannt.

In [94]: df.rename_axis(columns="Cols").columns
Out[94]: RangeIndex(start=0, stop=2, step=1, name='Cols')

Rename und rename_axis unterstützen die Angabe eines Wörterbuchs, einer Serie und einer Zuordnungsfunktion, um eine Bezeichnung / einen Namen einem neuen Wert zuzuordnen.

Wenn Sie direkt mit dem Index-Objekt anstatt über den DataFrame arbeiten möchten, dann Index.set_names () Sie können es mit .set_names.html # pandas.Index.set_names umbenennen.

In [95]: mi = pd.MultiIndex.from_product([[1, 2], ['a', 'b']], names=['x', 'y'])

In [96]: mi.names
Out[96]: FrozenList(['x', 'y'])

In [97]: mi2 = mi.rename("new name", level=0)

In [98]: mi2
Out[98]:
MultiIndex([(1, 'a'),
            (1, 'b'),
            (2, 'a'),
            (2, 'b')],
           names=['new name', 'y'])

: Warnung: ** Warnung ** Vor Pandas 1.0.0 war es auch möglich, den Namen des MultiIndex durch Aktualisieren des Namens der Ebene festzulegen.

>>> mi.levels[0].name = 'name via level'
>>> mi.names[0]  # only works for older panads
'name via level'

Ab pandas 1.0 kann der Name von MultiIndex implizit nicht aktualisiert werden. Verwenden Sie stattdessen Index.set_names () Bitte gib mir.

Sortieren von "MultiIndex"

Objekte mit "MultiIndex" müssen sortiert werden, um effektiv indiziert und in Scheiben geschnitten zu werden. Wie jeder andere Index sort_index () Du kannst es benutzen.

In [99]: import random

In [100]: random.shuffle(tuples)

In [101]: s = pd.Series(np.random.randn(8), index=pd.MultiIndex.from_tuples(tuples))

In [102]: s
Out[102]:
qux  one    0.206053
foo  two   -0.251905
bar  two   -2.213588
     one    1.063327
qux  two    1.266143
baz  one    0.299368
foo  one   -0.863838
baz  two    0.408204
dtype: float64

In [103]: s.sort_index()
Out[103]:
bar  one    1.063327
     two   -2.213588
baz  one    0.299368
     two    0.408204
foo  one   -0.863838
     two   -0.251905
qux  one    0.206053
     two    1.266143
dtype: float64

In [104]: s.sort_index(level=0)
Out[104]:
bar  one    1.063327
     two   -2.213588
baz  one    0.299368
     two    0.408204
foo  one   -0.863838
     two   -0.251905
qux  one    0.206053
     two    1.266143
dtype: float64

In [105]: s.sort_index(level=1)
Out[105]:
bar  one    1.063327
baz  one    0.299368
foo  one   -0.863838
qux  one    0.206053
bar  two   -2.213588
baz  two    0.408204
foo  two   -0.251905
qux  two    1.266143
dtype: float64

Wenn die Ebene von "MultiIndex" benannt ist, können Sie den Ebenennamen auch an "sort_index" übergeben.

In [106]: s.index.set_names(['L1', 'L2'], inplace=True)

In [107]: s.sort_index(level='L1')
Out[107]:
L1   L2
bar  one    1.063327
     two   -2.213588
baz  one    0.299368
     two    0.408204
foo  one   -0.863838
     two   -0.251905
qux  one    0.206053
     two    1.266143
dtype: float64

In [108]: s.sort_index(level='L2')
Out[108]:
L1   L2
bar  one    1.063327
baz  one    0.299368
foo  one   -0.863838
qux  one    0.206053
bar  two   -2.213588
baz  two    0.408204
foo  two   -0.251905
qux  two    1.266143
dtype: float64

Wenn Sie für höherdimensionale Objekte über "MultiIndex" verfügen, können Sie auf anderen Achsen als dem Index nach Ebenen sortieren.

In [109]: df.T.sort_index(level=1, axis=1)
Out[109]:
        one      zero       one      zero
          x         x         y         y
0  0.600178  2.410179  1.519970  0.132885
1  0.274230  1.450520 -0.493662 -0.023688

Die Indizierung funktioniert auch dann, wenn die Daten nicht sortiert sind, aber ziemlich ineffizient (und Sie sehen eine "PerformanceWarning"). Es wird auch eine Kopie der Daten anstelle der Ansicht zurückgegeben.

In [110]: dfm = pd.DataFrame({'jim': [0, 0, 1, 1],
   .....:                     'joe': ['x', 'x', 'z', 'y'],
   .....:                     'jolie': np.random.rand(4)})
   .....:

In [111]: dfm = dfm.set_index(['jim', 'joe'])

In [112]: dfm
Out[112]:
            jolie
jim joe
0   x    0.490671
    x    0.120248
1   z    0.537020
    y    0.110968
In [4]: dfm.loc[(1, 'z')]
PerformanceWarning: indexing past lexsort depth may impact performance.

Out[4]:
           jolie
jim joe
1   z    0.64094

Darüber hinaus kann die Indizierung, wenn sie nicht vollständig sortiert ist, zu folgendem Fehler führen:

In [5]: dfm.loc[(0, 'y'):(1, 'z')]
UnsortedIndexError: 'Key length (2) was greater than MultiIndex lexsort depth (1)'

Die Methode is_lexsorted () von MultiIndex ist ein Index. Gibt an, ob sortiert ist, und die Eigenschaft lexsort_depth gibt die Sortiertiefe zurück.

In [113]: dfm.index.is_lexsorted()
Out[113]: False

In [114]: dfm.index.lexsort_depth
Out[114]: 1
In [115]: dfm = dfm.sort_index()

In [116]: dfm
Out[116]:
            jolie
jim joe
0   x    0.490671
    x    0.120248
1   y    0.110968
    z    0.537020

In [117]: dfm.index.is_lexsorted()
Out[117]: True

In [118]: dfm.index.lexsort_depth
Out[118]: 2

Die Auswahl funktioniert jetzt wie erwartet.

In [119]: dfm.loc[(0, 'y'):(1, 'z')]
Out[119]:
            jolie
jim joe
1   y    0.110968
    z    0.537020

Methode nehmen

Wie NumPy ndarrays bietet auch pandas Index · Series · DataFrame eine take () Methode, um Elemente entlang einer bestimmten Achse an einem bestimmten Index abzurufen. Der angegebene Index muss ein ndarray an der Position der Liste oder des ganzzahligen Index sein. take kann auch negative ganze Zahlen relativ zum Ende des Objekts akzeptieren.

In [120]: index = pd.Index(np.random.randint(0, 1000, 10))

In [121]: index
Out[121]: Int64Index([214, 502, 712, 567, 786, 175, 993, 133, 758, 329], dtype='int64')

In [122]: positions = [0, 9, 3]

In [123]: index[positions]
Out[123]: Int64Index([214, 329, 567], dtype='int64')

In [124]: index.take(positions)
Out[124]: Int64Index([214, 329, 567], dtype='int64')

In [125]: ser = pd.Series(np.random.randn(10))

In [126]: ser.iloc[positions]
Out[126]:
0   -0.179666
9    1.824375
3    0.392149
dtype: float64

In [127]: ser.take(positions)
Out[127]:
0   -0.179666
9    1.824375
3    0.392149
dtype: float64

Für DataFrame muss der angegebene Index eine eindimensionale Liste oder ein ndarray sein, das die Zeilen- oder Spaltenposition angibt.

In [128]: frm = pd.DataFrame(np.random.randn(5, 3))

In [129]: frm.take([1, 4, 3])
Out[129]:
          0         1         2
1 -1.237881  0.106854 -1.276829
4  0.629675 -1.425966  1.857704
3  0.979542 -1.633678  0.615855

In [130]: frm.take([0, 2], axis=1)
Out[130]:
          0         2
0  0.595974  0.601544
1 -1.237881 -1.276829
2 -0.767101  1.499591
3  0.979542  0.615855
4  0.629675  1.857704

Beachten Sie, dass die Methode "take" des Pandas-Objekts nicht für die Verwendung mit Booleschen Indizes vorgesehen ist und unerwartete Ergebnisse zurückgeben kann.

In [131]: arr = np.random.randn(10)

In [132]: arr.take([False, False, True, True])
Out[132]: array([-1.1935, -1.1935,  0.6775,  0.6775])

In [133]: arr[[0, 1]]
Out[133]: array([-1.1935,  0.6775])

In [134]: ser = pd.Series(np.random.randn(10))

In [135]: ser.take([False, False, True, True])
Out[135]:
0    0.233141
0    0.233141
1   -0.223540
1   -0.223540
dtype: float64

In [136]: ser.iloc[[0, 1]]
Out[136]:
0    0.233141
1   -0.223540
dtype: float64

Ein kleiner Hinweis zur Leistung: Die Methode "take" behandelt einen engeren Bereich von Eingaben, wodurch eine viel schnellere Leistung erzielt werden kann als bei einem ausgefallenen Index. ]]

In [137]: arr = np.random.randn(10000, 5)

In [138]: indexer = np.arange(10000)

In [139]: random.shuffle(indexer)

In [140]: %timeit arr[indexer]
   .....: %timeit arr.take(indexer, axis=0)
   .....:
219 us +- 1.23 us per loop (mean +- std. dev. of 7 runs, 1000 loops each)
72.3 us +- 727 ns per loop (mean +- std. dev. of 7 runs, 10000 loops each)
In [141]: ser = pd.Series(arr[:, 0])

In [142]: %timeit ser.iloc[indexer]
   .....: %timeit ser.take(indexer)
   .....:
179 us +- 1.54 us per loop (mean +- std. dev. of 7 runs, 10000 loops each)
162 us +- 1.6 us per loop (mean +- std. dev. of 7 runs, 10000 loops each)

Indextyp

Bisher haben wir den "MultiIndex" ziemlich ausführlich behandelt. Die Dokumentation für "DatetimeIndex" und "PeriodIndex" ist hier, die Dokumentation für "TimedeltaIndex" ist [hier](https: / Siehe /dev.pandas.io/docs/user_guide/timedeltas.html#timedeltas-index).

In den folgenden Unterabschnitten werden einige andere Indextypen hervorgehoben.

CategoricalIndex

CategoricalIndex ist ein Index, der die Unterstützung doppelter Indizes unterstützt. .. Dies ist ein Container, der Categorical mit vielen doppelten Elementen umgibt. Ermöglicht die effiziente Indizierung und Speicherung von Indizes, die enthalten.

In [143]: from pandas.api.types import CategoricalDtype

In [144]: df = pd.DataFrame({'A': np.arange(6),
   .....:                    'B': list('aabbca')})
   .....:

In [145]: df['B'] = df['B'].astype(CategoricalDtype(list('cab')))

In [146]: df
Out[146]:
   A  B
0  0  a
1  1  a
2  2  b
3  3  b
4  4  c
5  5  a

In [147]: df.dtypes
Out[147]:
A       int64
B    category
dtype: object

In [148]: df['B'].cat.categories
Out[148]: Index(['c', 'a', 'b'], dtype='object')

Durch das Setzen des Index wird ein CategoricalIndex erstellt.

In [149]: df2 = df.set_index('B')

In [150]: df2.index
Out[150]: CategoricalIndex(['a', 'a', 'b', 'b', 'c', 'a'], categories=['c', 'a', 'b'], ordered=False, name='B', dtype='category')

Indizes, die __getitem__ /. Iloc / .loc verwenden, funktionieren genauso wie Index. Der Indexer muss ** zu einer Kategorie gehören **. Andernfalls erhalten Sie einen "KeyError".

In [151]: df2.loc['a']
Out[151]:
   A
B
a  0
a  1
a  5

Der CategoricalIndex wird nach dem Index ** beibehalten **.

In [152]: df2.loc['a'].index
Out[152]: CategoricalIndex(['a', 'a', 'a'], categories=['c', 'a', 'b'], ordered=False, name='B', dtype='category')

Wenn Sie die Indizes sortieren, werden sie nach Kategorien sortiert (da Sie den Index mit "CategoricalDtype (list (" cab "))" erstellt haben, werden sie nach "cab" sortiert).

In [153]: df2.sort_index()
Out[153]:
   A
B
c  4
a  0
a  1
a  5
b  2
b  3

Groupby-Operationen für Indizes behalten auch die Eigenschaften des Index bei.

In [154]: df2.groupby(level=0).sum()
Out[154]:
   A
B
c  4
a  6
b  5

In [155]: df2.groupby(level=0).sum().index
Out[155]: CategoricalIndex(['c', 'a', 'b'], categories=['c', 'a', 'b'], ordered=False, name='B', dtype='category')

Die Neuindizierungsoperation gibt einen Index des Ergebnisses zurück, der auf dem Typ des übergebenen Indexers basiert. Wenn Sie eine Liste übergeben, wird ein normaler "Index" zurückgegeben. Durch Übergeben eines Categorical wird einCategoricalIndex zurückgegeben, der gemäß der übergebenen Kategorie ** Categoricaldtype indiziert ist. Auf diese Weise können Sie willkürlich Werte indizieren, die ** in der Kategorie nicht vorhanden sind, ähnlich wie Sie Pandas neu indizieren.

In [156]: df3 = pd.DataFrame({'A': np.arange(3),
   .....:                     'B': pd.Series(list('abc')).astype('category')})
   .....:

In [157]: df3 = df3.set_index('B')

In [158]: df3
Out[158]:
   A
B
a  0
b  1
c  2
In [159]: df3.reindex(['a', 'e'])
Out[159]:
     A
B
a  0.0
e  NaN

In [160]: df3.reindex(['a', 'e']).index
Out[160]: Index(['a', 'e'], dtype='object', name='B')

In [161]: df3.reindex(pd.Categorical(['a', 'e'], categories=list('abe')))
Out[161]:
     A
B
a  0.0
e  NaN

In [162]: df3.reindex(pd.Categorical(['a', 'e'], categories=list('abe'))).index
Out[162]: CategoricalIndex(['a', 'e'], categories=['a', 'b', 'e'], ordered=False, name='B', dtype='category')

: Warnung: ** Warnung ** Formatierungs- und Vergleichsvorgänge in CategoricalIndex müssen in derselben Kategorie sein. Andernfalls erhalten Sie einen "TypeError".

In [163]: df4 = pd.DataFrame({'A': np.arange(2),
   .....:                     'B': list('ba')})
   .....:

In [164]: df4['B'] = df4['B'].astype(CategoricalDtype(list('ab')))

In [165]: df4 = df4.set_index('B')

In [166]: df4.index
Out[166]: CategoricalIndex(['b', 'a'], categories=['a', 'b'], ordered=False, name='B', dtype='category')

In [167]: df5 = pd.DataFrame({'A': np.arange(2),
   .....:                     'B': list('bc')})
   .....:

In [168]: df5['B'] = df5['B'].astype(CategoricalDtype(list('bc')))

In [169]: df5 = df5.set_index('B')

In [170]: df5.index
Out[170]: CategoricalIndex(['b', 'c'], categories=['b', 'c'], ordered=False, name='B', dtype='category')
In [1]: pd.concat([df4, df5])
TypeError: categories must match existing categories when appending

Int64Index und RangeIndex

Int64Index ist die Grundlage der Pandas-Index-Stiftung. Dies ist ein unveränderliches Array, das eine geordnete Slicable-Menge implementiert.

RangeIndex stellt den Standardindex für alle NDFrame-Objekte bereit Eine Unterklasse von "Int64Index". RangeIndex ist eine Version von Int64Index, die für die Darstellung einer monotonen Reihe von Aufträgen optimiert wurde. Diese ähneln Pythons range type.

Float64Index

Standardmäßig ist Float64Index eine schwebende Minderheit oder Ganzzahl bei der Indizierung. Wird automatisch erstellt, wenn ein gemischter Wert aus schwebenden Brüchen übergeben wird. Dies ermöglicht ein reines Label-basiertes Slicing-Paradigma, bei dem der Skalarindex und das Slicing [], ix und loc genau gleich funktionieren.

In [171]: indexf = pd.Index([1.5, 2, 3, 4.5, 5])

In [172]: indexf
Out[172]: Float64Index([1.5, 2.0, 3.0, 4.5, 5.0], dtype='float64')

In [173]: sf = pd.Series(range(5), index=indexf)

In [174]: sf
Out[174]:
1.5    0
2.0    1
3.0    2
4.5    3
5.0    4
dtype: int64

Skalare Auswahlen für "[]" und ".loc" basieren immer auf Beschriftungen. Die Angabe einer Ganzzahl entspricht einem gleichen Float-Index (z. B. entspricht "3" "3.0").

In [175]: sf[3]
Out[175]: 2

In [176]: sf[3.0]
Out[176]: 2

In [177]: sf.loc[3]
Out[177]: 2

In [178]: sf.loc[3.0]
Out[178]: 2

Der einzige Positionsindex ist über "iloc".

In [179]: sf.iloc[3]
Out[179]: 3

Der nicht gefundene Skalarindex löst einen "KeyError" aus. Slices basieren hauptsächlich auf Indexwerten, wenn "[]", "ix" und "loc" verwendet werden, und ** basieren immer auf der Position, wenn "iloc" verwendet wird. Die Ausnahme ist, wenn das Slice ein boolescher Wert ist. In diesem Fall basiert es immer auf der Position.

In [180]: sf[2:4]
Out[180]:
2.0    1
3.0    2
dtype: int64

In [181]: sf.loc[2:4]
Out[181]:
2.0    1
3.0    2
dtype: int64

In [182]: sf.iloc[2:4]
Out[182]:
3.0    2
4.5    3
dtype: int64

Mit dem Float-Index können Sie Slices mit Floating-Brüchen verwenden.

In [183]: sf[2.1:4.6]
Out[183]:
3.0    2
4.5    3
dtype: int64

In [184]: sf.loc[2.1:4.6]
Out[184]:
3.0    2
4.5    3
dtype: int64

Wenn es sich nicht um einen Float-Index handelt, lösen Slices, die Floats verwenden, einen "TypeError" aus.

In [1]: pd.Series(range(5))[3.5]
TypeError: the label [3.5] is not a proper indexer for this index type (Int64Index)

In [1]: pd.Series(range(5))[3.5:4.5]
TypeError: the slice start [3.5] is not a proper indexer for this index type (Int64Index)

Die folgenden Anwendungsfälle werden häufig für die Verwendung dieses Indextyps verwendet: Stellen Sie sich ein unregelmäßiges zeitdeltaartiges Indexierungsschema vor, bei dem die Daten als Floats aufgezeichnet werden. Dies kann beispielsweise ein Millisekundenversatz sein.

In [185]: dfir = pd.concat([pd.DataFrame(np.random.randn(5, 2),
   .....:                                index=np.arange(5) * 250.0,
   .....:                                columns=list('AB')),
   .....:                   pd.DataFrame(np.random.randn(6, 2),
   .....:                                index=np.arange(4, 10) * 250.1,
   .....:                                columns=list('AB'))])
   .....:

In [186]: dfir
Out[186]:
               A         B
0.0    -0.435772 -1.188928
250.0  -0.808286 -0.284634
500.0  -1.815703  1.347213
750.0  -0.243487  0.514704
1000.0  1.162969 -0.287725
1000.4 -0.179734  0.993962
1250.5 -0.212673  0.909872
1500.6 -0.733333 -0.349893
1750.7  0.456434 -0.306735
2000.8  0.553396  0.166221
2250.9 -0.101684 -0.734907

Auswahloperationen arbeiten für alle Auswahloperatoren immer auf Wertbasis.

In [187]: dfir[0:1000.4]
Out[187]:
               A         B
0.0    -0.435772 -1.188928
250.0  -0.808286 -0.284634
500.0  -1.815703  1.347213
750.0  -0.243487  0.514704
1000.0  1.162969 -0.287725
1000.4 -0.179734  0.993962

In [188]: dfir.loc[0:1001, 'A']
Out[188]:
0.0      -0.435772
250.0    -0.808286
500.0    -1.815703
750.0    -0.243487
1000.0    1.162969
1000.4   -0.179734
Name: A, dtype: float64

In [189]: dfir.loc[1000.4]
Out[189]:
A   -0.179734
B    0.993962
Name: 1000.4, dtype: float64

Sie können die erste Sekunde (1000 Millisekunden) der Daten wie folgt abrufen:

In [190]: dfir[0:1000]
Out[190]:
               A         B
0.0    -0.435772 -1.188928
250.0  -0.808286 -0.284634
500.0  -1.815703  1.347213
750.0  -0.243487  0.514704
1000.0  1.162969 -0.287725

Wenn Sie eine auf einer ganzzahligen Position basierende Auswahl benötigen, verwenden Sie "iloc".

In [191]: dfir.iloc[0:5]
Out[191]:
               A         B
0.0    -0.435772 -1.188928
250.0  -0.808286 -0.284634
500.0  -1.815703  1.347213
750.0  -0.243487  0.514704
1000.0  1.162969 -0.287725

IntervalIndex

IntervalIndex und seinen eigenen D-Typ IntervalDtype und Interval Mit dem Skalartyp können Pandas erstklassige Unterstützung für die Intervallnotation bieten. Ich werde.

IntervalIndex ermöglicht eine eindeutige Indizierung, [cut ()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.cut.html#pandas Als Rückgabetyp der Kategorien .cut) und qcut () Wird auch verwendet.

Index von IntervalIndex

IntervalIndex kann als Index in Series und DataFrame verwendet werden.

In [192]: df = pd.DataFrame({'A': [1, 2, 3, 4]},
   .....:                   index=pd.IntervalIndex.from_breaks([0, 1, 2, 3, 4]))
   .....:

In [193]: df
Out[193]:
        A
(0, 1]  1
(1, 2]  2
(2, 3]  3
(3, 4]  4

Beschriftungsbasierte Indizes über ".loc", die den Enden des Intervalls folgen, funktionieren wie erwartet und wählen dieses bestimmte Intervall aus.

In [194]: df.loc[2]
Out[194]:
A    2
Name: (1, 2], dtype: int64

In [195]: df.loc[[2, 3]]
Out[195]:
        A
(1, 2]  2
(2, 3]  3

Wenn Sie die Bezeichnung * enthalten * innerhalb eines Intervalls auswählen, wird sie für jedes Intervall ausgewählt.

In [196]: df.loc[2.5]
Out[196]:
A    3
Name: (2, 3], dtype: int64

In [197]: df.loc[[2.5, 3.5]]
Out[197]:
        A
(2, 3]  3
(3, 4]  4

Bei Auswahl in Intervallen werden nur genaue Übereinstimmungen zurückgegeben (Pandas 0.25.0 und höher).

In [198]: df.loc[pd.Interval(1, 2)]
Out[198]:
A    2
Name: (1, 2], dtype: int64

Wenn Sie versuchen, ein Intervall auszuwählen, das nicht genau im "IntervalIndex" enthalten ist, erhalten Sie einen "KeyError".

In [7]: df.loc[pd.Interval(0.5, 2.5)]
---------------------------------------------------------------------------
KeyError: Interval(0.5, 2.5, closed='right')

Um alle "Intervalle" auszuwählen, die ein bestimmtes "Intervall" überlappen, "überlappt ()". Erstellen Sie einen booleschen Indexer mit der Methode overraps.html # pandas.IntervalIndex.overlaps).

In [199]: idxr = df.index.overlaps(pd.Interval(0.5, 2.5))

In [200]: idxr
Out[200]: array([ True,  True,  True, False])

In [201]: df[idxr]
Out[201]:
        A
(0, 1]  1
(1, 2]  2
(2, 3]  3

Binning-Daten mit cut und qcut

cut () und [qcut ()](https: / /pandas.pydata.org/pandas-docs/stable/reference/api/pandas.qcut.html#pandas.qcut) geben beide kategoriale Objekte zurück und die von ihnen erstellten Bins befinden sich im Attribut ".categories". Es wird als IntervalIndex` gespeichert.

In [202]: c = pd.cut(range(4), bins=2)

In [203]: c
Out[203]:
[(-0.003, 1.5], (-0.003, 1.5], (1.5, 3.0], (1.5, 3.0]]
Categories (2, interval[float64]): [(-0.003, 1.5] < (1.5, 3.0]]

In [204]: c.categories
Out[204]:
IntervalIndex([(-0.003, 1.5], (1.5, 3.0]],
              closed='right',
              dtype='interval[float64]')

cut () übergibt IntervalIndex als Argument 'bins kann auch tun. Dies ermöglicht eine bequeme Pandas-Sprache. Setzen Sie zunächst einige Daten und "Bins" auf eine feste Zahl [cut ()`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.cut). Rufen Sie html # pandas.cut) auf, um einen Bin zu erstellen. Als nächstes wurde der Wert von ".categories" anschließend ["cut ()"] genannt (https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.cut.html#) Sie können neue Daten in demselben Bin zusammenfassen, indem Sie sie an das Argument "bins" von pandas.cut übergeben.

In [205]: pd.cut([0, 3, 5, 1], bins=c.categories)
Out[205]:
[(-0.003, 1.5], (1.5, 3.0], NaN, (-0.003, 1.5]]
Categories (2, interval[float64]): [(-0.003, 1.5] < (1.5, 3.0]]

Werte außerhalb aller Bins erhalten den NaN-Wert.

Erstellen einer Reihe von Intervallen

Wenn Sie Intervalle mit normaler Frequenz benötigen, verwenden Sie die Funktion interval_range (). Sie können es verwenden, um einen "IntervalIndex" mit verschiedenen Kombinationen von "Start", "Ende" und "Perioden" zu erstellen. Der Standardzeitraum für interval_range ist 1 für numerische Intervalle und Kalendertage für datetime-ähnliche Intervalle.

In [206]: pd.interval_range(start=0, end=5)
Out[206]:
IntervalIndex([(0, 1], (1, 2], (2, 3], (3, 4], (4, 5]],
              closed='right',
              dtype='interval[int64]')

In [207]: pd.interval_range(start=pd.Timestamp('2017-01-01'), periods=4)
Out[207]:
IntervalIndex([(2017-01-01, 2017-01-02], (2017-01-02, 2017-01-03], (2017-01-03, 2017-01-04], (2017-01-04, 2017-01-05]],
              closed='right',
              dtype='interval[datetime64[ns]]')

In [208]: pd.interval_range(end=pd.Timedelta('3 days'), periods=3)
Out[208]:
IntervalIndex([(0 days 00:00:00, 1 days 00:00:00], (1 days 00:00:00, 2 days 00:00:00], (2 days 00:00:00, 3 days 00:00:00]],
              closed='right',
              dtype='interval[timedelta64[ns]]')

Das Argument "freq" kann verwendet werden, um einen nicht standardmäßigen Zeitraum mit verschiedenen "Zeitraum-Aliasnamen" für datetime-ähnliche Intervalle anzugeben. # timeseries-offset-aliases) ist verfügbar.

In [209]: pd.interval_range(start=0, periods=5, freq=1.5)
Out[209]:
IntervalIndex([(0.0, 1.5], (1.5, 3.0], (3.0, 4.5], (4.5, 6.0], (6.0, 7.5]],
              closed='right',
              dtype='interval[float64]')

In [210]: pd.interval_range(start=pd.Timestamp('2017-01-01'), periods=4, freq='W')
Out[210]:
IntervalIndex([(2017-01-01, 2017-01-08], (2017-01-08, 2017-01-15], (2017-01-15, 2017-01-22], (2017-01-22, 2017-01-29]],
              closed='right',
              dtype='interval[datetime64[ns]]')

In [211]: pd.interval_range(start=pd.Timedelta('0 days'), periods=3, freq='9H')
Out[211]:
IntervalIndex([(0 days 00:00:00, 0 days 09:00:00], (0 days 09:00:00, 0 days 18:00:00], (0 days 18:00:00, 1 days 03:00:00]],
              closed='right',
              dtype='interval[timedelta64[ns]]')

Darüber hinaus können Sie mit dem Argument "geschlossen" angeben, wer das Intervall schließt. Standardmäßig sind die Intervalle rechts geschlossen.

In [212]: pd.interval_range(start=0, end=4, closed='both')
Out[212]:
IntervalIndex([[0, 1], [1, 2], [2, 3], [3, 4]],
              closed='both',
              dtype='interval[int64]')

In [213]: pd.interval_range(start=0, end=4, closed='neither')
Out[213]:
IntervalIndex([(0, 1), (1, 2), (2, 3), (3, 4)],
              closed='neither',
              dtype='interval[int64]')

_ Ab Version 0.23.0 _

Wenn Sie "Start", "Ende" und "Perioden" angeben, erstellt der resultierende "IntervalIndex" ein Intervall von "Start" bis "Ende" mit so vielen Elementen wie "Perioden" in gleichen Intervallen.

In [214]: pd.interval_range(start=0, end=6, periods=4)
Out[214]:
IntervalIndex([(0.0, 1.5], (1.5, 3.0], (3.0, 4.5], (4.5, 6.0]],
              closed='right',
              dtype='interval[float64]')

In [215]: pd.interval_range(pd.Timestamp('2018-01-01'),
   .....:                   pd.Timestamp('2018-02-28'), periods=3)
   .....:
Out[215]:
IntervalIndex([(2018-01-01, 2018-01-20 08:00:00], (2018-01-20 08:00:00, 2018-02-08 16:00:00], (2018-02-08 16:00:00, 2018-02-28]],
              closed='right',
              dtype='interval[datetime64[ns]]')

Andere häufig gestellte Fragen zur Indizierung

Index nach Ganzzahl

Die beschriftungsbasierte Indizierung mit Ganzzahlachsenbeschriftungen ist ein heikles Thema. Es wird häufig unter verschiedenen Mitgliedern der Mailingliste und der wissenschaftlichen Python-Community diskutiert. Bei Pandas ist unsere allgemeine Ansicht, dass Beschriftungen wichtiger sind als ganzzahlige Positionen. Daher ermöglichen Standardwerkzeuge wie ".loc" für ganzzahlige Achsenindizes die beschriftungsbasierte Indizierung * nur *. Der folgende Code löst eine Ausnahme aus.

In [216]: s = pd.Series(range(5))

In [217]: s[-1]
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-217-76c3dce40054> in <module>
----> 1 s[-1]

~/work/1/s/pandas/core/series.py in __getitem__(self, key)
   1076         key = com.apply_if_callable(key, self)
   1077         try:
-> 1078             result = self.index.get_value(self, key)
   1079
   1080             if not is_scalar(result):

~/work/1/s/pandas/core/indexes/base.py in get_value(self, series, key)
   4623         k = self._convert_scalar_indexer(k, kind="getitem")
   4624         try:
-> 4625             return self._engine.get_value(s, k, tz=getattr(series.dtype, "tz", None))
   4626         except KeyError as e1:
   4627             if len(self) > 0 and (self.holds_integer() or self.is_boolean()):

~/work/1/s/pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_value()

~/work/1/s/pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_value()

~/work/1/s/pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

~/work/1/s/pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item()

~/work/1/s/pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item()

KeyError: -1

In [218]: df = pd.DataFrame(np.random.randn(5, 4))

In [219]: df
Out[219]:
          0         1         2         3
0 -0.130121 -0.476046  0.759104  0.213379
1 -0.082641  0.448008  0.656420 -1.051443
2  0.594956 -0.151360 -0.069303  1.221431
3 -0.182832  0.791235  0.042745  2.069775
4  1.446552  0.019814 -1.389212 -0.702312

In [220]: df.loc[-2:]
Out[220]:
          0         1         2         3
0 -0.130121 -0.476046  0.759104  0.213379
1 -0.082641  0.448008  0.656420 -1.051443
2  0.594956 -0.151360 -0.069303  1.221431
3 -0.182832  0.791235  0.042745  2.069775
4  1.446552  0.019814 -1.389212 -0.702312

Diese bewusste Entscheidung wurde getroffen, um Mehrdeutigkeiten und subtile Fehler zu vermeiden (viele Benutzer finden einen Fehler, wenn sie die API so ändern, dass der "Fallback" bei der positionsbasierten Indizierung gestoppt wird. Ich berichtete).

Genaue Übereinstimmung für nicht monotone Indizes erforderlich

Wenn der Index des "Series" - oder "DataFrame" monoton zunimmt oder abnimmt, liegt der Rand der beschriftungsbasierten Slices möglicherweise außerhalb des Bereichs des Index, wie bei der normalen Python-Listen-Slice-Indizierung. Die Monotonie des Index ist is_monotonic_increasing () und Sie können mit dem Attribut is_monotonic_decreasing () testen.

In [221]: df = pd.DataFrame(index=[2, 3, 3, 4, 5], columns=['data'], data=list(range(5)))

In [222]: df.index.is_monotonic_increasing
Out[222]: True

#Die Zeilen 0, 1 existieren nicht, geben jedoch die Zeilen 2, 3 (beide), 4 zurück
In [223]: df.loc[0:4, :]
Out[223]:
   data
2     0
3     1
3     2
4     3

#Ein leerer DataFrame wird zurückgegeben, da das Slice keinen Index mehr hat
In [224]: df.loc[13:15, :]
Out[224]:
Empty DataFrame
Columns: [data]
Index: []

Wenn der Index hingegen nicht eintönig ist, müssen beide Slice-Grenzen * eindeutige * Werte des Index sein.

In [225]: df = pd.DataFrame(index=[2, 3, 1, 4, 3, 5],
   .....:                   columns=['data'], data=list(range(6)))
   .....:

In [226]: df.index.is_monotonic_increasing
Out[226]: False

#Es gibt kein Problem, da sowohl 2 als auch 4 im Index enthalten sind
In [227]: df.loc[2:4, :]
Out[227]:
   data
2     0
3     1
1     2
4     3
#0 existiert nicht im Index
In [9]: df.loc[0:4, :]
KeyError: 0

#3 ist kein eindeutiges Etikett
In [11]: df.loc[2:3, :]
KeyError: 'Cannot get right slice bound for non-unique label: 3'

Index.is_monotonic_increasing und Index.is_monotonic_decreasing prüfen nur leicht, ob der Index eintönig ist. Um die genaue Monotonie zu sehen, wählen Sie entweder [is_unique ()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Index.is_unique.html# Kombinieren Sie mit dem Attribut pandas.Index.is_unique).

In [228]: weakly_monotonic = pd.Index(['a', 'b', 'c', 'c'])

In [229]: weakly_monotonic
Out[229]: Index(['a', 'b', 'c', 'c'], dtype='object')

In [230]: weakly_monotonic.is_monotonic_increasing
Out[230]: True

In [231]: weakly_monotonic.is_monotonic_increasing & weakly_monotonic.is_unique
Out[231]: False

Endpunkt ist enthalten

Im Gegensatz zu Standard-Python-Sequenz-Slices, die keine Endpunkte enthalten, tun dies Pandas-Label-basierte Slices. Der Hauptgrund dafür ist, dass es oft nicht einfach ist, das "nachfolgende Label" oder das nächste Element nach einem bestimmten Label im Index zu bestimmen. Betrachten Sie zum Beispiel die folgenden "Seires".

In [232]: s = pd.Series(np.random.randn(6), index=list('abcdef'))

In [233]: s
Out[233]:
a    0.301379
b    1.240445
c   -0.846068
d   -0.043312
e   -1.658747
f   -0.819549
dtype: float64

Angenommen, Sie möchten mit einer Ganzzahl von c nach e schneiden. Dies geschieht wie folgt:

In [234]: s[2:5]
Out[234]:
c   -0.846068
d   -0.043312
e   -1.658747
dtype: float64

Wenn Sie jedoch nur "c" und "e" angeben, kann die Bestimmung des nächsten Elements im Index etwas kompliziert sein. Zum Beispiel funktioniert Folgendes nicht:

s.loc['c':'e' + 1]

Ein sehr häufiger Anwendungsfall ist die Angabe einer bestimmten Zeitreihe, die an zwei bestimmten Daten beginnt und endet. Um dies zu ermöglichen, haben wir das Label-basierte Slice so konzipiert, dass es beide Endpunkte enthält.

In [235]: s.loc['c':'e']
Out[235]:
c   -0.846068
d   -0.043312
e   -1.658747
dtype: float64

Dies ist wohl "praktischer als rein", aber seien Sie vorsichtig, wenn Sie erwarten, dass sich markenbasierte Slices genau wie Standard-Python-Ganzzahl-Slices verhalten.

Indizierung, die implizit den dtype der Serie ändert

Verschiedene Indizierungsvorgänge können den dtype von Series ändern.

In [236]: series1 = pd.Series([1, 2, 3])

In [237]: series1.dtype
Out[237]: dtype('int64')

In [238]: res = series1.reindex([0, 4])

In [239]: res.dtype
Out[239]: dtype('float64')

In [240]: res
Out[240]:
0    1.0
4    NaN
dtype: float64
In [241]: series2 = pd.Series([True])

In [242]: series2.dtype
Out[242]: dtype('bool')

In [243]: res = series2.reindex_like(series1)

In [244]: res.dtype
Out[244]: dtype('O')

In [245]: res
Out[245]:
0    True
1     NaN
2     NaN
dtype: object

Dies liegt daran, dass die obige (Neu-) Indizierungsoperation implizit "NaNs" einfügt und den "dtype" entsprechend ändert. Dies kann Probleme bei der Verwendung von "numpy ufuncs" wie "numpy.logical_and" verursachen.

Weitere Informationen finden Sie in dieser früheren Ausgabe (https://github.com/pydata/pandas/issues/2388).

Recommended Posts

Pandas Benutzerhandbuch "Multi-Index / Advanced Index" (offizielles Dokument Japanische Übersetzung)
Pandas Benutzerhandbuch "Manipulieren fehlender Daten" (offizielles Dokument Japanische Übersetzung)
Pandas Benutzerhandbuch "Tabellenformatierung und Pivot-Tabelle" (offizielles Dokument Japanische Übersetzung)
Pandas Benutzerhandbuch "Zusammenführen und Verbinden und Verketten" (offizielles Dokument Japanische Übersetzung)
[Übersetzung] scikit-learn 0.18 Benutzerhandbuch 4.5. Zufällige Projektion
[Übersetzung] scikit-learn 0.18 Benutzerhandbuch 1.11. Ensemble-Methode
[Übersetzung] scikit-learn 0.18 Benutzerhandbuch 1.15. Isotonische Regression
[Übersetzung] scikit-learn 0.18 Benutzerhandbuch 4.2 Merkmalsextraktion
[Übersetzung] scikit-learn 0.18 Benutzerhandbuch 1.16. Wahrscheinlichkeitskalibrierung
[Übersetzung] scikit-learn 0.18 Benutzerhandbuch 1.13 Funktionsauswahl
[Übersetzung] scikit-learn 0.18 Benutzerhandbuch 3.4. Modellpersistenz
[Übersetzung] scikit-learn 0.18 Benutzerhandbuch 2.8. Dichteschätzung
[Übersetzung] scikit-learn 0.18 Benutzerhandbuch 4.3. Datenvorverarbeitung
Japanische Übersetzung des Apache Spark-Dokuments - Einreichen von Anträgen
[Übersetzung] scikit-learn 0.18 Benutzerhandbuch 4.4. Unüberwachte Dimensionsreduzierung
[Übersetzung] scikit-learn 0.18 Benutzerhandbuch Inhaltsverzeichnis
[Übersetzung] scikit-learn 0.18 Benutzerhandbuch 1.4. Support Vector Machine
Verwendung von FastAPI ② Erweitert - Benutzerhandbuch
Japanische Übersetzung des Apache Spark-Dokuments - Schnellstart
[Google App Engine] Benutzerobjekte (japanische Übersetzung)