Pandalar MultiIndex DataFrame'deki satırları seçin


147

İndeksi MultiIndex olan bir veri çerçevesinin satırlarını seçmenin / filtrelemenin en yaygın Pandaların yolları nelerdir ?

  • Tek bir değer / etikete göre dilimleme
  • Bir veya daha fazla düzeydeki birden çok etikete göre dilimleme
  • Boole koşullarını ve ifadelerini filtreleme
  • Hangi durumlarda hangi yöntemler uygulanabilir?

Basitlik varsayımları:

  1. girdi veri çerçevesi yinelenen dizin anahtarlarına sahip değil
  2. aşağıdaki girdi veri çerçevesi yalnızca iki seviyeye sahiptir. (Burada gösterilen çözümlerin çoğu N düzeyine genelleştirilmiştir)

Örnek giriş:

mux = pd.MultiIndex.from_arrays([
    list('aaaabbbbbccddddd'),
    list('tuvwtuvwtuvwtuvw')
], names=['one', 'two'])

df = pd.DataFrame({'col': np.arange(len(mux))}, mux)

         col
one two     
a   t      0
    u      1
    v      2
    w      3
b   t      4
    u      5
    v      6
    w      7
    t      8
c   u      9
    v     10
d   w     11
    t     12
    u     13
    v     14
    w     15

Soru 1: Tek Bir Öğe Seçme

Düzey "bir" de "a" içeren satırları nasıl seçerim?

         col
one two     
a   t      0
    u      1
    v      2
    w      3

Ek olarak, çıktıda "bir" seviyesini nasıl düşürebilirim?

     col
two     
t      0
u      1
v      2
w      3

Soru 1b
"İki" düzeyinde "t" değerine sahip tüm satırları nasıl dilimleyebilirim?

         col
one two     
a   t      0
b   t      4
    t      8
d   t     12

Soru 2: Bir Düzeyde Birden Çok Değer Seçme

Düzey "bir" de "b" ve "d" öğelerine karşılık gelen satırları nasıl seçebilirim?

         col
one two     
b   t      4
    u      5
    v      6
    w      7
    t      8
d   w     11
    t     12
    u     13
    v     14
    w     15

Soru 2b
Düzey "iki" de "t" ve "w" ye karşılık gelen tüm değerleri nasıl elde ederim?

         col
one two     
a   t      0
    w      3
b   t      4
    w      7
    t      8
d   w     11
    t     12
    w     15

Soru 3: Tek Bir Kesiti Dilimleme (x, y)

Bir enine kesiti, yani indeks için belirli değerlere sahip tek bir satırı nereden alabilirim df? Özellikle, ('c', 'u')tarafından verilen kesitini nasıl alırım

         col
one two     
c   u      9

Soru 4: Birden Çok Kesiti Dilimleme [(a, b), (c, d), ...]

Nasıl karşılık gelen iki satır seçerim ('c', 'u')ve ('a', 'w')?

         col
one two     
c   u      9
a   w      3

Soru 5: Seviye Başına Bir Öğe Dilimlenmiş

Düzey "bir" de "a" veya "iki" düzeyindeki "t" ye karşılık gelen tüm satırları nasıl alabilirim?

         col
one two     
a   t      0
    u      1
    v      2
    w      3
b   t      4
    t      8
d   t     12

Soru 6: Keyfi Dilimleme

Belirli kesitleri nasıl dilimleyebilirim? "A" ve "b" için, "u" ve "v" alt düzeylerine sahip tüm satırları seçmek istiyorum ve "d" için, alt düzeyi "w" olan satırları seçmek istiyorum.

         col
one two     
a   u      1
    v      2
b   u      5
    v      6
d   w     11
    w     15

Soru 7, sayısal seviyeden oluşan benzersiz bir kurulum kullanacaktır:

np.random.seed(0)
mux2 = pd.MultiIndex.from_arrays([
    list('aaaabbbbbccddddd'),
    np.random.choice(10, size=16)
], names=['one', 'two'])

df2 = pd.DataFrame({'col': np.arange(len(mux2))}, mux2)

         col
one two     
a   5      0
    0      1
    3      2
    3      3
b   7      4
    9      5
    3      6
    5      7
    2      8
c   4      9
    7     10
d   6     11
    8     12
    8     13
    1     14
    6     15

Soru 7: Çoklu indeksin bireysel seviyelerinde sayısal eşitsizliğe göre filtreleme

Düzey "iki" deki değerlerin 5'ten büyük olduğu tüm satırları nasıl elde ederim?

         col
one two     
b   7      4
    9      5
c   7     10
d   6     11
    8     12
    8     13
    6     15

Not: Bu yazı olacak değil onlara atama işlemlerini gerçekleştirmek veya herhangi bir performans ile ilgili tartışmalar (bu başka bir zaman için ayrı konulardır) nasıl MultiIndexes, nasıl oluşturulacağını geçer.

Yanıtlar:


166

MultiIndex / Gelişmiş İndeksleme

Not
Bu gönderi aşağıdaki şekilde yapılandırılacaktır:

  1. OP'de ortaya konan sorular tek tek ele alınacaktır.
  2. Her soru için, bu problemi çözmek ve beklenen sonucu elde etmek için geçerli olan bir veya daha fazla yöntem gösterilecektir.

Notlar (buna çok benzer), ek işlevsellik, uygulama ayrıntıları ve eldeki konuyla ilgili diğer bilgileri öğrenmekle ilgilenen okuyucular için dahil edilecektir. Bu notlar, belgeleri inceleyerek ve çeşitli belirsiz özellikleri ortaya çıkararak ve benim (kuşkusuz sınırlı) deneyimlerime dayanarak derlendi.

Tüm kod örnekleri pandalar v0.23.4, python3.7 üzerinde oluşturulmuş ve test edilmiştir . Bir şey net değilse veya gerçeklere göre yanlışsa ya da kullanım alanınıza uygun bir çözüm bulamadıysanız, lütfen bir düzenleme önermekten, yorumlarda açıklama istemekten veya yeni bir soru açmaktan çekinmeyin. .

İşte sık sık tekrar ziyaret edeceğimiz bazı yaygın deyimlere (bundan böyle Dört Deyim olarak anılacaktır) bir giriş.

  1. DataFrame.loc- Etikete göre seçim için genel bir çözüm (+ pd.IndexSlicedilimleri içeren daha karmaşık uygulamalar için)

  2. DataFrame.xs - Seri / Veri Çerçevesinden belirli bir kesiti çıkarın.

  3. DataFrame.query- Dilimleme ve / veya filtreleme işlemlerini dinamik olarak belirtin (yani, dinamik olarak değerlendirilen bir ifade olarak. Bazı senaryolar için diğerlerinden daha uygundur. Ayrıca MultiIndexes üzerinde sorgulama için belgelerin bu bölümüne bakın .

  4. Kullanılarak oluşturulan bir maske ile Boole dizini oluşturma MultiIndex.get_level_values( Index.isinözellikle birden çok değerle filtreleme yaparken genellikle ile bağlantılı olarak ). Bu aynı zamanda bazı durumlarda oldukça kullanışlıdır.

Belirli bir duruma neyin uygulanabileceğini daha iyi anlamak için çeşitli dilimleme ve filtreleme problemlerine Dört Deyim açısından bakmak faydalı olacaktır. Tüm deyimlerin her durumda eşit derecede iyi çalışmayacağını (eğer varsa) anlamak çok önemlidir. Bir deyim aşağıda bir soruna potansiyel çözüm olarak listelenmemişse, bu, deyimin o soruna etkili bir şekilde uygulanamayacağı anlamına gelir.


Soru 1

Düzey "bir" de "a" içeren satırları nasıl seçerim?

         col
one two     
a   t      0
    u      1
    v      2
    w      3

locÇoğu durumda geçerli olan genel amaçlı bir çözüm olarak kullanabilirsiniz :

df.loc[['a']]

Bu noktada, eğer alırsan

TypeError: Expected tuple, got str

Bu, pandaların eski bir sürümünü kullandığınız anlamına gelir. Yükseltmeyi düşünün! Aksi takdirde kullanın df.loc[('a', slice(None)), :].

Alternatif olarak, xstek bir kesit çıkardığımız için burayı kullanabilirsiniz . Not levelsve axis(makul varsayılan burada varsayılabilir) argümanlar.

df.xs('a', level=0, axis=0, drop_level=False)
# df.xs('a', drop_level=False)

Burada, sonuçtaki "bir" düzeyinin (dilimlediğimiz düzey) düşmesini drop_level=Falseönlemek için argüman gereklidir xs.

Yine burada başka bir seçenek kullanmak query:

df.query("one == 'a'")

Dizinin bir adı yoksa, sorgu dizenizi olarak değiştirmeniz gerekir "ilevel_0 == 'a'".

Son olarak, şunu kullanarak get_level_values:

df[df.index.get_level_values('one') == 'a']
# If your levels are unnamed, or if you need to select by position (not label),
# df[df.index.get_level_values(0) == 'a']

Ek olarak, çıktıda "bir" seviyesini nasıl düşürebilirim?

     col
two     
t      0
u      1
v      2
w      3

Bu, aşağıdakilerden biri kullanılarak kolayca yapılabilir

df.loc['a'] # Notice the single string argument instead the list.

Veya,

df.xs('a', level=0, axis=0, drop_level=True)
# df.xs('a')

drop_levelArgümanı atlayabileceğimize dikkat edin (varsayılan olarak olduğu Truevarsayılır).

Not
Filtrelenmiş bir DataFrame'in, DataFrame dışarı yazdırılırken gösterilmese bile tüm düzeylere sahip olabileceğini fark edebilirsiniz. Örneğin,

v = df.loc[['a']]
print(v)
         col
one two     
a   t      0
    u      1
    v      2
    w      3

print(v.index)
MultiIndex(levels=[['a', 'b', 'c', 'd'], ['t', 'u', 'v', 'w']],
           labels=[[0, 0, 0, 0], [0, 1, 2, 3]],
           names=['one', 'two'])

Şunları kullanarak bu seviyelerden kurtulabilirsiniz MultiIndex.remove_unused_levels:

v.index = v.index.remove_unused_levels()

print(v.index)
MultiIndex(levels=[['a'], ['t', 'u', 'v', 'w']],
           labels=[[0, 0, 0, 0], [0, 1, 2, 3]],
           names=['one', 'two'])

Soru 1b

Düzey "iki" de "t" değerine sahip tüm satırları nasıl dilimleyebilirim?

         col
one two     
a   t      0
b   t      4
    t      8
d   t     12

Sezgisel olarak, aşağıdakileri içeren bir şey istersiniz slice():

df.loc[(slice(None), 't'), :]

It Just Works! ™ Ama hantal. pd.IndexSliceBurada API'yi kullanarak daha doğal bir dilimleme sözdizimini kolaylaştırabiliriz .

idx = pd.IndexSlice
df.loc[idx[:, 't'], :]

Bu çok çok daha temiz.

Not Sütunların
sonundaki dilim neden :gerekli? Bunun nedeni, locher iki eksen ( axis=0veya axis=1) boyunca seçmek ve dilimlemek için kullanılabilmesidir . Dilimlemenin hangi eksende yapılacağını açıkça belirtmeden işlem belirsizleşir. Dilimleme ile ilgili belgelerdeki büyük kırmızı kutuya bakın .

Herhangi bir belirsizlik gölgesini kaldırmak istiyorsanız, locbir axis parametre kabul eder :

df.loc(axis=0)[pd.IndexSlice[:, 't']]

axisParametre olmadan (yani, sadece yaparak df.loc[pd.IndexSlice[:, 't']]), dilimlemenin sütunlarda olduğu varsayılır ve KeyErrorbu durumda a yükseltilecektir.

Bu, dilimleyicilerde belgelenmiştir . Bununla birlikte, bu yazının amacı için, tüm eksenleri açıkça belirteceğiz.

İle xs, öyle

df.xs('t', axis=0, level=1, drop_level=False)

İle query, öyle

df.query("two == 't'")
# Or, if the first level has no name, 
# df.query("ilevel_1 == 't'") 

Ve son olarak, get_level_valuesyapabilirsin

df[df.index.get_level_values('two') == 't']
# Or, to perform selection by position/integer,
# df[df.index.get_level_values(1) == 't']

Hepsi aynı etkiye.


soru 2

Düzey "bir" de "b" ve "d" öğelerine karşılık gelen satırları nasıl seçebilirim?

         col
one two     
b   t      4
    u      5
    v      6
    w      7
    t      8
d   w     11
    t     12
    u     13
    v     14
    w     15

Loc kullanarak, bu da benzer bir şekilde bir liste belirleyerek yapılır.

df.loc[['b', 'd']]

Seçimi "b" ve "d" nin yukarıdaki sorunu çözmek için ayrıca kullanabilirsiniz query:

items = ['b', 'd']
df.query("one in @items")
# df.query("one == @items", parser='pandas')
# df.query("one in ['b', 'd']")
# df.query("one == ['b', 'd']", parser='pandas')

Not
Evet, varsayılan ayrıştırıcıdır 'pandas', ancak bu sözdiziminin geleneksel olarak python olmadığını vurgulamak önemlidir. Pandalar ayrıştırıcısı, ifadeden biraz farklı bir ayrıştırma ağacı oluşturur. Bu, bazı işlemleri daha sezgisel hale getirmek için yapılır. Daha fazla bilgi için lütfen pd.eval () kullanarak pandalarda Dinamik İfade Değerlendirmesi hakkındaki yazımı okuyun .

Ve get_level_values+ ile Index.isin:

df[df.index.get_level_values("one").isin(['b', 'd'])]

Soru 2b

Düzey "iki" de "t" ve "w" ye karşılık gelen tüm değerleri nasıl elde ederim?

         col
one two     
a   t      0
    w      3
b   t      4
    w      7
    t      8
d   w     11
    t     12
    w     15

İle locbu sadece ile birlikte mümkündür pd.IndexSlice.

df.loc[pd.IndexSlice[:, ['t', 'w']], :] 

Birinci kolon :içinde pd.IndexSlice[:, ['t', 'w']]vasıtasıyla ilk seviye boyunca dilim. Sorgulanan seviyenin derinliği arttıkça, her seviye için dilimlenecek şekilde daha fazla dilim belirtmeniz gerekecektir. Bununla birlikte, dilimlenenin ötesinde daha fazla seviye belirlemenize gerek yoktur .

İle querybu

items = ['t', 'w']
df.query("two in @items")
# df.query("two == @items", parser='pandas') 
# df.query("two in ['t', 'w']")
# df.query("two == ['t', 'w']", parser='pandas')

İle get_level_valuesve Index.isin(yukarıdakine benzer):

df[df.index.get_level_values('two').isin(['t', 'w'])]

Soru 3

Bir enine kesiti, yani indeks için belirli değerlere sahip tek bir satırı nereden alabilirim df? Özellikle, ('c', 'u')tarafından verilen kesitini nasıl alırım

         col
one two     
c   u      9

Kullanım loctuşlarının bir demet belirterek:

df.loc[('c', 'u'), :]

Veya,

df.loc[pd.IndexSlice[('c', 'u')]]

Not
Bu noktada, PerformanceWarningşuna benzer bir ile karşılaşabilirsiniz:

PerformanceWarning: indexing past lexsort depth may impact performance.

Bu sadece dizininizin sıralanmadığı anlamına gelir. Pandalar, optimum arama ve erişim için sıralanan dizine bağlıdır (bu durumda, dizgi değerleriyle uğraştığımız için sözlükbilimsel olarak). Hızlı bir düzeltme, DataFrame'inizi kullanarak önceden sıralamak olacaktır DataFrame.sort_index. Bu tür birden çok sorguyu art arda yapmayı planlıyorsanız, bu özellikle performans açısından istenir:

df_sort = df.sort_index()
df_sort.loc[('c', 'u')]

Ayrıca MultiIndex.is_lexsorted()dizinin sıralı olup olmadığını kontrol etmek için de kullanabilirsiniz . Bu işlev Trueveya Falsebuna göre döner . Ek bir sıralama adımının gerekli olup olmadığını belirlemek için bu işlevi çağırabilirsiniz.

İle xs, bu yine, diğer tüm argümanlar uygun varsayılan değerlerine ayarlanmış olarak, ilk argüman olarak tek bir demeti iletmektir:

df.xs(('c', 'u'))

İle queryişler biraz hantal hale geliyor:

df.query("one == 'c' and two == 'u'")

Şimdi bunu genellemenin nispeten zor olacağını görebilirsiniz. Ancak bu özel sorun için hala sorun yok.

Birden çok seviyeye yayılan erişimlerle get_level_values, yine de kullanılabilir, ancak önerilmez:

m1 = (df.index.get_level_values('one') == 'c')
m2 = (df.index.get_level_values('two') == 'u')
df[m1 & m2]

Soru 4

Nasıl karşılık gelen iki satır seçerim ('c', 'u')ve ('a', 'w')?

         col
one two     
c   u      9
a   w      3

Bununla birlikte loc, bu hala şu kadar basit:

df.loc[[('c', 'u'), ('a', 'w')]]
# df.loc[pd.IndexSlice[[('c', 'u'), ('a', 'w')]]]

İle query, kesitlerinizi ve seviyelerinizi yineleyerek dinamik olarak bir sorgu dizisi oluşturmanız gerekecektir:

cses = [('c', 'u'), ('a', 'w')]
levels = ['one', 'two']
# This is a useful check to make in advance.
assert all(len(levels) == len(cs) for cs in cses) 

query = '(' + ') or ('.join([
    ' and '.join([f"({l} == {repr(c)})" for l, c in zip(levels, cs)]) 
    for cs in cses
]) + ')'

print(query)
# ((one == 'c') and (two == 'u')) or ((one == 'a') and (two == 'w'))

df.query(query)

% 100 TAVSİYE ETMEYİN! Ama mümkün.


Soru 5

Düzey "bir" de "a" veya "iki" düzeyindeki "t" ye karşılık gelen tüm satırları nasıl alabilirim?

         col
one two     
a   t      0
    u      1
    v      2
    w      3
b   t      4
    t      8
d   t     12

locDoğruluğu sağlarken ve yine de kod netliğini korurken bunu yapmak aslında çok zordur . df.loc[pd.IndexSlice['a', 't']]yanlış olarak yorumlanır df.loc[pd.IndexSlice[('a', 't')]](yani, bir kesit seçme). pd.concatHer etiketi ayrı ayrı ele almak için bir çözüm düşünebilirsiniz :

pd.concat([
    df.loc[['a'],:], df.loc[pd.IndexSlice[:, 't'],:]
])

         col
one two     
a   t      0
    u      1
    v      2
    w      3
    t      0   # Does this look right to you? No, it isn't!
b   t      4
    t      8
d   t     12

Ancak satırlardan birinin kopyalandığını fark edeceksiniz. Bunun nedeni, bu satırın hem dilimleme koşullarını karşılaması hem de iki kez görünmesidir. Bunun yerine yapmanız gerekecek

v = pd.concat([
        df.loc[['a'],:], df.loc[pd.IndexSlice[:, 't'],:]
])
v[~v.index.duplicated()]

Ancak DataFrame'iniz doğası gereği yinelenen endeksler içeriyorsa (istediğiniz), o zaman bu onları tutmayacaktır. Çok dikkatli kullanın .

Bununla queryaptalca basit:

df.query("one == 'a' or two == 't'")

Bununla birlikte get_level_values, bu hala basit, ancak o kadar zarif değil:

m1 = (df.index.get_level_values('one') == 'a')
m2 = (df.index.get_level_values('two') == 't')
df[m1 | m2] 

Soru 6

Belirli kesitleri nasıl dilimleyebilirim? "A" ve "b" için, "u" ve "v" alt düzeylerine sahip tüm satırları seçmek istiyorum ve "d" için, alt düzeyi "w" olan satırları seçmek istiyorum.

         col
one two     
a   u      1
    v      2
b   u      5
    v      6
d   w     11
    w     15

Bu, Dört Deyimin uygulanabilirliğini anlamaya yardımcı olmak için eklediğim özel bir durumdur - bu, dilimleme çok özel olduğundan ve herhangi bir gerçek modeli takip etmediğinden hiçbirinin etkili bir şekilde çalışmayacağı bir durumdur .

Genellikle, bunun gibi dilimleme problemleri, anahtarlarının bir listesini açıkça iletmeyi gerektirir loc. Bunu yapmanın bir yolu şudur:

keys = [('a', 'u'), ('a', 'v'), ('b', 'u'), ('b', 'v'), ('d', 'w')]
df.loc[keys, :]

Bazı yazımları kaydetmek istiyorsanız, "a", "b" ve alt seviyelerini dilimlemek için bir kalıp olduğunu fark edeceksiniz, böylece dilimleme görevini iki kısma ayırabiliriz ve concatsonuç:

pd.concat([
     df.loc[(('a', 'b'), ('u', 'v')), :], 
     df.loc[('d', 'w'), :]
   ], axis=0)

"A" ve "b" için dilimleme (('a', 'b'), ('u', 'v'))özelliği, indekslenen aynı alt düzeyler her düzey için aynı olduğundan biraz daha temizdir .


Soru 7

Düzey "iki" deki değerlerin 5'ten büyük olduğu tüm satırları nasıl elde ederim?

         col
one two     
b   7      4
    9      5
c   7     10
d   6     11
    8     12
    8     13
    6     15

Bu kullanılarak yapılabilir query,

df2.query("two > 5")

Ve get_level_values.

df2[df2.index.get_level_values('two') > 5]

Not
Bu örneğe benzer şekilde, bu yapıları kullanarak herhangi bir keyfi koşula göre filtre uygulayabiliriz. Genel olarak, hatırlamak faydalıdır locve xssüre, etiket bazlı endeksleme için özel olan queryve get_level_valuesfiltreleme için genel koşullu maskeleri oluşturmak için faydalıdır.


Bonus soru

Ya bir MultiIndex sütunu dilimlemem gerekirse ?

Aslında, buradaki çoğu çözüm, küçük değişikliklerle birlikte sütunlara da uygulanabilir. Düşünmek:

np.random.seed(0)
mux3 = pd.MultiIndex.from_product([
        list('ABCD'), list('efgh')
], names=['one','two'])

df3 = pd.DataFrame(np.random.choice(10, (3, len(mux))), columns=mux3)
print(df3)

one  A           B           C           D         
two  e  f  g  h  e  f  g  h  e  f  g  h  e  f  g  h
0    5  0  3  3  7  9  3  5  2  4  7  6  8  8  1  6
1    7  7  8  1  5  9  8  9  4  3  0  3  5  0  2  3
2    8  1  3  3  3  7  0  1  9  9  0  4  7  3  2  7

Bunlar, sütunlarla çalışmasını sağlamak için Dört Deyimde yapmanız gereken aşağıdaki değişikliklerdir.

  1. Birlikte dilimlemek için lockullanın

    df3.loc[:, ....] # Notice how we slice across the index with `:`. 

    veya,

    df3.loc[:, pd.IndexSlice[...]]
  2. xsUygun şekilde kullanmak için bir argüman iletmeniz yeterlidir axis=1.

  3. Doğrudan kullanarak sütun seviyesi değerlerine erişebilirsiniz df.columns.get_level_values. Daha sonra şunun gibi bir şey yapmanız gerekecek

    df.loc[:, {condition}] 

    Burada {condition}kullanılarak inşa edilen bazı koşulları temsil eder columns.get_level_values.

  4. Kullanmak queryiçin tek seçeneğiniz sırasını değiştirmek, dizini sorgulamak ve yeniden sıralamaktır:

    df3.T.query(...).T

    Önerilmez, diğer 3 seçenekten birini kullanın.


6

Son zamanlarda, yukarıdaki çözümlerden hiçbirinin aradığım sonuçları üretmesini sağlayamadığım 3+ seviyeli çoklu dizin veri çerçevesine sahip olduğum bir kullanım durumuyla karşılaştım. Yukarıdaki çözümlerin elbette benim kullanım durumum için işe yaraması oldukça olasıdır ve birkaçını denedim, ancak mevcut zamanımla onları çalıştırmayı başaramadım.

Uzman olmaktan çok uzağım, ancak yukarıdaki kapsamlı yanıtlarda listelenmeyen bir çözüme rastladım. Çözümlerin herhangi bir şekilde optimal olduğuna dair hiçbir garanti sunmuyorum.

Bu, yukarıdaki Soru 6'dan biraz farklı bir sonuç almanın farklı bir yoludur. (ve muhtemelen diğer sorular da)

Özellikle arıyordum:

  1. Dizinin bir düzeyinden iki + değer ve dizinin başka bir düzeyinden tek bir değer seçmenin bir yolu ve
  2. Veri çerçevesi çıktısında önceki işlemin dizin değerlerini bırakmanın bir yolu.

Dişlilerde bir maymun anahtarı olarak (ancak tamamen sabitlenebilir):

  1. Dizinler isimsizdi.

Aşağıdaki oyuncak veri çerçevesinde:

    index = pd.MultiIndex.from_product([['a','b'],
                               ['stock1','stock2','stock3'],
                               ['price','volume','velocity']])

    df = pd.DataFrame([1,2,3,4,5,6,7,8,9,
                      10,11,12,13,14,15,16,17,18], 
                       index)

                        0
    a stock1 price      1
             volume     2
             velocity   3
      stock2 price      4
             volume     5
             velocity   6
      stock3 price      7
             volume     8
             velocity   9
    b stock1 price     10
             volume    11
             velocity  12
      stock2 price     13
             volume    14
             velocity  15
      stock3 price     16
             volume    17
             velocity  18

Elbette aşağıdaki çalışmaları kullanmak:

    df.xs(('stock1', 'velocity'), level=(1,2))

        0
    a   3
    b  12

Ama farklı bir sonuç istedim, bu yüzden bu sonucu alma yöntemim şuydu:

   df.iloc[df.index.isin(['stock1'], level=1) & 
           df.index.isin(['velocity'], level=2)] 

                        0
    a stock1 velocity   3
    b stock1 velocity  12

Ve bir seviyeden iki + değer ve başka bir seviyeden tek bir (veya 2+) değer istersem:

    df.iloc[df.index.isin(['stock1','stock3'], level=1) & 
            df.index.isin(['velocity'], level=2)] 

                        0
    a stock1 velocity   3
      stock3 velocity   9
    b stock1 velocity  12
      stock3 velocity  18

Yukarıdaki yöntem muhtemelen biraz kullanışsızdır, ancak bunun ihtiyaçlarımı karşıladığını ve bonus olarak anlamak ve okumak benim için daha kolay olduğunu gördüm.


2
Güzel, leveltartışmasını bilmiyordum Index.isin!
cs95
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.