Pandas'ın concat işlevindeki 'düzeyler', 'anahtarlar' ve isim argümanları nelerdir?


98

Sorular

  • Nasıl kullanırım pd.concat?
  • levelsArgüman ne için?
  • keysArgüman ne için?
  • Tüm argümanların nasıl kullanılacağını açıklamaya yardımcı olacak bir dizi örnek var mı?

Pandaların concatişlevi, birleştirme hizmetlerinin İsviçre çakısıdır. Yararlı olduğu durumların çeşitliliği çoktur. Mevcut dokümantasyon, bazı isteğe bağlı argümanlar hakkında birkaç ayrıntıyı dışarıda bırakır. Bunların arasında levelsve keysargümanlar var. Bu argümanların ne işe yaradığını anlamaya başladım.

Bunun birçok yönüne bir geçit görevi görecek bir soru soracağım pd.concat.

Veri çerçevelerini düşünün d1, d2ve 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])

Bunları birlikte birleştirirsem

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

Nesnem için bir ile beklenen sonucu pandas.MultiIndexalıyorum columns:

        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

Ancak, levelsargüman belgelerini kullanmak istedim :

düzeyler : dizi listesi, varsayılan Yok. Bir MultiIndex oluşturmak için kullanılacak belirli seviyeler (benzersiz değerler). Aksi takdirde, anahtarlardan çıkarılacaklardır.

Bu yüzden geçtim

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

Ve bir al KeyError

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

Bu mantıklıydı. Geçtiğim seviyeler, tuşların belirttiği gerekli seviyeleri tanımlamak için yetersizdi. Yukarıda yaptığım gibi hiçbir şeyi geçmemiş olsaydım, seviyeler çıkarılır (belgelerde belirtildiği gibi). Ama bu argümanı daha iyi etki için başka nasıl kullanabilirim?

Bunun yerine bunu denediysem:

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

Ben ve yukarıdaki ile aynı sonuçları aldım. Ancak seviyelere bir değer daha eklediğimde,

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

Aynı görünümlü veri çerçevesiyle sonuçlandım, ancak sonuçta MultiIndexkullanılmayan bir seviye var.

df.index.levels[0]

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

Öyleyse levelargümanın amacı nedir ve keysfarklı şekilde kullanmalı mıyım?

Python 3.6 ve Pandas 0.22 kullanıyorum.

Yanıtlar:


130

Bu soruyu kendim için cevaplama sürecinde çok şey öğrendim ve bir örnek kataloğu ve bazı açıklamalar hazırlamak istedim.

levelsTartışmanın noktasına özel cevap sona doğru gelecektir.

pandas.concat: Eksik Kılavuz

Mevcut Belgelere Bağlantı

Nesneleri içe aktarır ve tanımlar

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])

Argümanlar

objs

Karşılaştığımız ilk argüman şudur objs:

objs : Series, DataFrame veya Panel nesnelerinin dizisi veya eşlemesi Bir dikte iletilirse, sıralanan anahtarlar, iletilmediği sürece anahtarlar bağımsız değişkeni olarak kullanılır ve bu durumda değerler seçilir (aşağıya bakın). Hiçbiri nesnesi, tümü Yok olmadıkça sessizce bırakılır; bu durumda bir Değer Hatası ortaya çıkar

  • Genellikle bunun bir Seriesveya DataFramenesneler listesi ile kullanıldığını görüyoruz .
  • Bunun dictda çok faydalı olabileceğini göstereceğim .
  • Jeneratörler de kullanılabilir ve olduğu gibi kullanıldığında yararlı olabilir map.map(f, list_of_df)

Şimdilik, yukarıda tanımlanan DataFrameve Seriesnesnelerin bazılarının bir listesine bağlı kalacağız . Çok yararlı MultiIndexsonuçlar vermek için sözlüklerden nasıl yararlanılabileceğini daha sonra göstereceğim .

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

Karşılaştığımız ikinci argüman axis, varsayılan değeri şudur 0:

eksen : {0 / 'dizin', 1 / 'sütunlar'}, varsayılan 0 Birlikte birleştirilecek eksen.

İki DataFrames ile axis=0(istiflenmiş)

Değerleri için 0veya indexşunu demek istiyoruz: "Sütunlar boyunca hizalayın ve dizine ekleyin".

Yukarıda gösterildiği gibi axis=0, çünkü 0varsayılan değerdir ve değerin örtüşmesine rağmen d2indeksinin indeksini genişlettiğini görüyoruz :d12

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

İki DataFrames ile axis=1(yan yana)

Değerler için 1veya columnsşunu demek istiyoruz: "Dizin boyunca hizalayın ve sütunlara ekleyin",

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

Ortaya çıkan endeks endekslerinin birliktir ve elde edilen kolonlar gelen sütunların uzantısı olduğunu görebiliyoruz d1sütunları ile d2.

İki (veya Üç) Seriesile axis=0(istiflenmiş)

Birleştirilirken pandas.Seriesbirlikte axis=0, biz geri almak pandas.Series. Ortaya çıkanların adı, birleştirilenlerin tümü aynı ada sahip olmadıkça Seriesolacaktır . Dikkat edin biz sonuçlanımını yazdırmak . Mevcut olmadığında, adın olduğunu varsayabiliriz .NoneSeries'Name: A'SeriesSeriesNone

               |                       |                        |  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

İki (veya Üç) Seriesile axis=1(yan yana)

Birleştirirken pandas.Seriesbirlikte axis=1, bunun namebiz elde edilen bir sütun adı anlaması için bakınız bu özellik 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

Karışık Seriesve DataFrameile axis=0(yığın)

Bir Seriesve DataFrameboyunca birleştirme gerçekleştirirken axis=0, hepsini Seriestek sütun DataFrames'ye dönüştürürüz .

Bunun bir bitiştirme olduğuna özellikle dikkat edin axis=0; bu, sütunları hizalarken dizini (satırları) genişletmek anlamına gelir. Aşağıdaki örneklerde [2, 3, 2, 3], endekslerin gelişigüzel eklenmesi olan endeksin olduğunu görüyoruz . Bağımsız Seriesdeğişken ile sütunun adlandırılmasını zorlamadıkça sütunlar çakışmaz: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

Sonuçlarını görebilirsiniz pd.concat([s1, d1])to_frame kendimi geliştirmişim gibi aynı olduğunu görebilirsiniz .

Ancak, elde edilen sütunun adını bir parametresi ile kontrol edebilirim to_frame. Yeniden adlandırma Seriesile renameyöntem etmez olup elde edilen sütun adı kontrolDataFrame .

 # 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

Karışık Series ve DataFrameile axis=1(yan yana)

Bu oldukça sezgiseldir. Seriessütun adı Series, bir nameöznitelik mevcut olmadığında varsayılan olarak bu tür nesnelerin bir numaralandırmasıdır .

                    |  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

Üçüncü argüman, joinortaya çıkan birleştirmenin bir dış birleştirme mi (varsayılan) yoksa bir iç birleştirme mi olması gerektiğini açıklar.

birleşim : {'iç', 'dış'}, varsayılan 'dış'
Diğer eksenlerde dizinler nasıl işlenir.

Görünüşe göre yok leftya da yokrightpd.concat göre, birleştirmek için iki nesneden daha fazlasını işleyebilecek bir seçenek .

Durumunda d1ve d2, seçenekler benziyor:

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

Dördüncü argüman, leftbirleşmemizi ve daha fazlasını yapmamızı sağlayan şeydir .

join_axes : Index nesnelerinin listesi
İç / dış küme mantığını gerçekleştirmek yerine diğer n - 1 eksenleri için kullanılacak özel indeksler.

Sol Birleştirme

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

Sağ Birleştirme

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, varsayılan False
If True, dizin değerlerini birleştirme ekseni boyunca kullanmayın. Ortaya çıkan eksen 0, ..., n - 1 olarak etiketlenecektir. Bu, birleştirme ekseninin anlamlı indeksleme bilgilerine sahip olmadığı nesneleri birleştiriyorsanız kullanışlıdır. Diğer eksenlerdeki dizin değerlerinin birleşimde hala dikkate alındığına dikkat edin.

d1Üst üste istiflediğimde olduğu gibi d2, indeks değerlerini umursamıyorsam, onları sıfırlayabilir veya görmezden gelebilirim.

                      |  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

Ve kullanırken 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

Karşılık gelen MultiIndex'e tuple veya skaler değerler atamak için bir skaler değerler veya tuple listesi geçirebiliriz. Aktarılan listenin uzunluğu, birleştirilen öğelerin sayısıyla aynı uzunlukta olmalıdır.

anahtarlar : sıra, varsayılan Yok
Birden fazla düzey geçtiyse, tuple içermelidir. En dış düzey olarak iletilen anahtarları kullanarak hiyerarşik dizin oluşturun

axis=0

SeriesNesneleri birleştirirkenaxis=0 (dizini genişletir).

Bu anahtarlar, MultiIndexindex niteliğindeki bir nesnenin yeni bir başlangıç ​​seviyesi haline gelir .

 #           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

Bununla birlikte, daha keysda derin oluşturmak için argümanda skaler değerlerden daha fazlasını kullanabiliriz MultiIndex. Burada tuplesuzunluk 2'nin başına iki yeni a düzeyini geçiyoruz 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

Sütunlar boyunca uzanırken biraz farklıdır. Kullandığımızda axis=0(yukarıya bakın) , mevcut dizine ek keysolarak MultiIndexseviyeler olarak hareket ettik . İçinaxis=1Series nesnelerin sahip olmadığı bir eksene , yani columnsniteliğe atıfta bulunuyoruz.

İkinin Varyasyonları Series gayrimenkulünüaxis=1

Bildirim adlandırma olduğunu s1ve s2bu kadar uzun diye konularda keysgeçirilir, ancak eğer geçersiz olur keysgeçirilir.

               |                       |                        |  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
MultiIndexile Seriesveaxis=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
İki DataFrame ileaxis=1

Olduğu gibi axis=0örneklerde, keysbir için seviyeleri eklemek MultiIndex, ama nesneye bu kez saklanan columnsöznitelik.

 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 ve DataFrame ileaxis=1

Bu aldatıcıdır. Bu durumda, bir skaler anahtar değeri için sadece endeksin seviyesi olarak hareket edemez Seriesda ilk seviyesi olarak hareket ederken, bir kolon olduğunda nesne MultiIndexiçin DataFrame. Böylece Pandalar , sütun adının kaynağı olarak nesnenin nameözniteliğini tekrar kullanacaktır Series.

 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
Sınırlamalar keysve MultiIndexçıkarım.

Pandalar yalnızca sütun adlarını Seriesadından çıkarıyor gibi görünmektedir , ancak farklı sayıda sütun düzeyine sahip veri çerçeveleri arasında benzer bir birleştirme yaparken boşlukları doldurmayacaktır.

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

Daha sonra, bunu sütun nesnesinde yalnızca bir seviyeye sahip başka bir veri çerçevesiyle birleştirin ve Pandalar, nesnenin demetlerini yapmayı MultiIndexve tüm veri çerçevelerini tek bir nesne, skaler ve demet seviyesi gibi birleştirmeyi reddeder .

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

A dictyerine a geçmeklist

Bir pandas.concatsözlüğü iletirken, keysparametre olarak sözlükteki anahtarları kullanacaktır .

 # 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

Bu, keysbağımsız değişkenle bağlantılı olarak kullanılır. levelsVarsayılan değeri olarak bırakıldığında None, Pandalar ortaya çıkan her seviyenin benzersiz değerlerini alacak MultiIndexve bunu sonuçta elde edilen index.levelsöznitelikte kullanılan nesne olarak kullanacaktır .

düzeyler : dizi listesi, varsayılan Yok
Bir MultiIndex oluşturmak için kullanılacak belirli düzeyler (benzersiz değerler). Aksi takdirde anahtarlardan çıkarılacaklardır.

Pandalar bu seviyelerin ne olması gerektiğini zaten anlamışsa, bunu kendimiz belirlemenin ne gibi bir avantajı var? Bir örnek göstereceğim ve bunun neden yararlı olabileceğine dair diğer nedenleri düşünmeyi size bırakacağım.

Misal

Belgelere göre, levelsargüman bir dizi listesidir. Bu pandas.Index, bu dizilerden biri olarak başka birini kullanabileceğimiz anlamına gelir .

Veri çerçevesini düşünün dfbirleşimidir d1, d2ve 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

Sütunlar nesnesinin seviyeleri şunlardır:

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

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

Kullandığımız Eğer sumbir dahilinde groupbyelde ederiz:

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

Peki ya ve ['First', 'Second', 'Fourth']adında başka bir eksik kategori varsa ? Ve bunların bir toplama işleminin sonuçlarına dahil edilmesini mi istedim ? Bunu bir . Ve bunu önceden belirtebiliriz.ThirdFifthgroupbypandas.CategoricalIndexlevels argümanla .

Onun yerine şöyle tanımlayalım 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

Ancak sütunlar nesnesinin ilk seviyesi:

df.columns.levels[0]

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

Ve groupbyözetimiz şöyle görünüyor:

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

Bu, sonuçta ortaya çıkan seviyeleri adlandırmak için kullanılır MultiIndex. namesListenin uzunluğu , sonuçtaki düzeylerin sayısıyla eşleşmelidir MultiIndex.

adlar : liste, varsayılan Hiçbiri
Ortaya çıkan hiyerarşik dizindeki düzeyler için adlar

 # 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

Kendinden açıklamalı belgeler

valid_integrity : boolean, varsayılan False
Yeni birleştirilmiş eksenin kopyalar içerip içermediğini kontrol edin. Bu, gerçek veri birleştirme işlemine göre çok pahalı olabilir.

Bitiştirmek kaynaklanan endeksi Çünkü d1ve d2eşsiz değil, doğruluk kontrolü yapmasını engeller.

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

Ve

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

> ValueError: Dizinler çakışan değerlere sahiptir: [2]


23
bazı eksik örnekleri (sadece bir çift) ana dokümanlara eklemek için basitçe bir çekme isteği yapmak topluluk için gerçekten çok daha yararlı olacaktır; SO yalnızca aranabilir ve göz atılamaz; Dokümanlara daha fazla bağlantı koymak burada yararlı olacaktır - bunun büyük çoğunluğu zaten iyi ve tamamen belgelenmiştir
Jeff

6
@Jeff büyümemin yavaş olan boyutları var. Git kullanmak bunlardan biridir. Söz veriyorum, yapmaya başlamak istediğim şey bu.
piRSquared

Kullanmaktan pd.concat(..., levels=[lvl]).groupby(axis=1, level=0).sum()farklı bir sonuç verir pd.concat(..., levels=[cats]).groupby(axis=1, level=0).sum(). Neden biliyor musun? Dokümanlar sadece levelsdizilerin bir listesi olması gerektiğini söylüyor .
unutbu

1
Harika cevap, ama bence bu bölüm Passing a dict instead of a listbir liste değil, dikt kullanan bir örneğe ihtiyaç duyar.
unutbu

1
@unutbu Örneği düzelttim dict, thx. Bunun nedeni lvlkategorik bir indeks ve catssadece bir liste. Kategorik bir türe göre gruplama yaparken, eksik kategoriler, uygun olduğu yerde sıfırlar ve boşlarla doldurulur. Bunu görün
piRSquared
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.