मल्टी-इंडेक्स पांडा से चयन


91

मेरे पास कॉलम 'ए' और 'बी' के साथ एक मल्टी-इंडेक्स डेटा फ्रेम है।

क्या इंडेक्स को सिंगल कॉलम इंडेक्स पर रीसेट किए बिना मल्टी-इंडेक्स के एक कॉलम पर फ़िल्टर करके पंक्तियों को चुनने का एक तरीका है?

उदाहरण के लिए।

# has multi-index (A,B)
df
#can I do this? I know this doesn't work because the index is multi-index so I need to     specify a tuple

df.ix[df.A ==1]


संबंधित: पांडा में पंक्तियों का चयन करें MultiIndex DataFrame (मेरे द्वारा एक ही विषय पर एक व्यापक चर्चा)।
cs95

जवाबों:


136

get_level_valuesसूचकांक विधि का उपयोग करने का एक तरीका है :

In [11]: df
Out[11]:
     0
A B
1 4  1
2 5  2
3 6  3

In [12]: df.iloc[df.index.get_level_values('A') == 1]
Out[12]:
     0
A B
1 4  1

0.13 में आप तर्क के xsसाथdrop_level उपयोग कर पाएंगे :

df.xs(1, level='A', drop_level=False) # axis=1 if columns

ध्यान दें: यदि यह अनुक्रमणिका के बजाय बहु-स्तंभ थे, तो आप एक ही तकनीक का उपयोग कर सकते हैं:

In [21]: df1 = df.T

In [22]: df1.iloc[:, df1.columns.get_level_values('A') == 1]
Out[22]:
A  1
B  4
0  1

53

तुम भी उपयोग कर सकते हैं queryजो मेरी राय में बहुत पठनीय और उपयोग करने के लिए सीधा है:

import pandas as pd

df = pd.DataFrame({'A': [1, 2, 3, 4], 'B': [10, 20, 50, 80], 'C': [6, 7, 8, 9]})
df = df.set_index(['A', 'B'])

      C
A B    
1 10  6
2 20  7
3 50  8
4 80  9

जो आपके मन में था उसके लिए अब आप बस कर सकते हैं:

df.query('A == 1')

      C
A B    
1 10  6

आप अधिक जटिल प्रश्नों का उपयोग भी कर सकते हैं and

df.query('A >= 1 and B >= 50')

      C
A B    
3 50  8
4 80  9

तथा or

df.query('A == 1 or B >= 50')

      C
A B    
1 10  6
3 50  8
4 80  9

आप विभिन्न इंडेक्स स्तरों पर भी क्वेरी कर सकते हैं , जैसे

df.query('A == 1 or C >= 8')

वापस होगा

      C
A B    
1 10  6
3 50  8
4 80  9

यदि आप अपनी क्वेरी के अंदर चर का उपयोग करना चाहते हैं, तो आप उपयोग कर सकते हैं@ :

b_threshold = 20
c_threshold = 8

df.query('B >= @b_threshold and C <= @c_threshold')

      C
A B    
2 20  7
3 50  8

1
महान जवाब, जिस तरह से वास्तव में अधिक पठनीय है। क्या आप जानते हैं कि अलग-अलग इंडेक्स स्तर पर दो फ़ील्ड को क्वेरी करना संभव है जैसे:df.query('A == 1 or C >= 8')
obchardon

@obchardon: यह ठीक काम करने लगता है; मैंने आपके उदाहरण का उपयोग करके अपना उत्तर संपादित किया।
क्लेब

1
मेरे पास कई बार और स्ट्रिंग्स मल्टींडेक्स के रूप में हैं जो स्ट्रिंग अभिव्यक्ति में समस्याएं बनाती हैं। हालाँकि, df.query()चर के साथ ठीक काम करता है अगर वे पर्यावरण में df.query('A == @varएक चर के लिए क्वेरी में उदाहरण के अंदर '@' के साथ संदर्भित हैं, जैसे ) var
सोलह

@Solly: धन्यवाद, मैंने इसे उत्तर में जोड़ा।
क्लीब

हालांकि बहु अनुक्रमण यहाँ कहाँ है?
लामा

32

आप उपयोग कर सकते हैं DataFrame.xs():

In [36]: df = DataFrame(np.random.randn(10, 4))

In [37]: df.columns = [np.random.choice(['a', 'b'], size=4).tolist(), np.random.choice(['c', 'd'], size=4)]

In [38]: df.columns.names = ['A', 'B']

In [39]: df
Out[39]:
A      b             a
B      d      d      d      d
0 -1.406  0.548 -0.635  0.576
1 -0.212 -0.583  1.012 -1.377
2  0.951 -0.349 -0.477 -1.230
3  0.451 -0.168  0.949  0.545
4 -0.362 -0.855  1.676 -2.881
5  1.283  1.027  0.085 -1.282
6  0.583 -1.406  0.327 -0.146
7 -0.518 -0.480  0.139  0.851
8 -0.030 -0.630 -1.534  0.534
9  0.246 -1.558 -1.885 -1.543

In [40]: df.xs('a', level='A', axis=1)
Out[40]:
B      d      d
0 -0.635  0.576
1  1.012 -1.377
2 -0.477 -1.230
3  0.949  0.545
4  1.676 -2.881
5  0.085 -1.282
6  0.327 -0.146
7  0.139  0.851
8 -1.534  0.534
9 -1.885 -1.543

यदि आप Aस्तर रखना चाहते हैं ( drop_levelकीवर्ड तर्क केवल v0.13.0 से शुरू हो रहा है):

In [42]: df.xs('a', level='A', axis=1, drop_level=False)
Out[42]:
A      a
B      d      d
0 -0.635  0.576
1  1.012 -1.377
2 -0.477 -1.230
3  0.949  0.545
4  1.676 -2.881
5  0.085 -1.282
6  0.327 -0.146
7  0.139  0.851
8 -1.534  0.534
9 -1.885 -1.543

1
हा, मैंने अपना उत्तर केवल उसी के साथ अपडेट किया था, नोट: केवल 0.13 में उपलब्ध है।
एंडी हेडन

ओह, जानकर अच्छा लगा। मुझे याद नहीं है कि प्रत्येक संस्करण में कौन सी छोटी-छोटी उपयुक्तताएँ जोड़ी जाती हैं।
फिलिप क्लाउड

लोल, वास्तव में यह प्रश्न उस सुविधा के लिए प्रेरित करने वाले का एक धोखा है! :)
एंडी हेडन

13

बहु-अनुक्रमित पंडों तक पहुंचने का तरीका समझना डेटाफ़्रेम आपको उस तरह के सभी प्रकार के कार्य में मदद कर सकता है।

उदाहरण बनाने के लिए अपने कोड में इसे कॉपी पेस्ट करें:

# hierarchical indices and columns
index = pd.MultiIndex.from_product([[2013, 2014], [1, 2]],
                                   names=['year', 'visit'])
columns = pd.MultiIndex.from_product([['Bob', 'Guido', 'Sue'], ['HR', 'Temp']],
                                     names=['subject', 'type'])

# mock some data
data = np.round(np.random.randn(4, 6), 1)
data[:, ::2] *= 10
data += 37

# create the DataFrame
health_data = pd.DataFrame(data, index=index, columns=columns)
health_data

आपको इस तरह से टेबल देगा:

यहाँ छवि विवरण दर्ज करें

स्तंभ द्वारा मानक पहुंच

health_data['Bob']
type       HR   Temp
year visit      
2013    1   22.0    38.6
        2   52.0    38.3
2014    1   30.0    38.9
        2   31.0    37.3


health_data['Bob']['HR']
year  visit
2013  1        22.0
      2        52.0
2014  1        30.0
      2        31.0
Name: HR, dtype: float64

# filtering by column/subcolumn - your case:
health_data['Bob']['HR']==22
year  visit
2013  1         True
      2        False
2014  1        False
      2        False

health_data['Bob']['HR'][2013]    
visit
1    22.0
2    52.0
Name: HR, dtype: float64

health_data['Bob']['HR'][2013][1]
22.0

पंक्ति द्वारा पहुँच

health_data.loc[2013]
subject Bob Guido   Sue
type    HR  Temp    HR  Temp    HR  Temp
visit                       
1   22.0    38.6    40.0    38.9    53.0    37.5
2   52.0    38.3    42.0    34.6    30.0    37.7

health_data.loc[2013,1] 
subject  type
Bob      HR      22.0
         Temp    38.6
Guido    HR      40.0
         Temp    38.9
Sue      HR      53.0
         Temp    37.5
Name: (2013, 1), dtype: float64

health_data.loc[2013,1]['Bob']
type
HR      22.0
Temp    38.6
Name: (2013, 1), dtype: float64

health_data.loc[2013,1]['Bob']['HR']
22.0

स्लाइसिंग मल्टी-इंडेक्स

idx=pd.IndexSlice
health_data.loc[idx[:,1], idx[:,'HR']]
    subject Bob Guido   Sue
type    HR  HR  HR
year    visit           
2013    1   22.0    40.0    53.0
2014    1   30.0    52.0    45.0

यह ValueError: cannot handle a non-unique multi-index!त्रुटि देता है
कोडेक्स

5

आप उपयोग कर सकते हैं DataFrame.loc:

>>> df.loc[1]

उदाहरण

>>> print(df)
       result
A B C        
1 1 1       6
    2       9
  2 1       8
    2      11
2 1 1       7
    2      10
  2 1       9
    2      12

>>> print(df.loc[1])
     result
B C        
1 1       6
  2       9
2 1       8
  2      11

>>> print(df.loc[2, 1])
   result
C        
1       7
2      10

यह आधुनिक दृष्टिकोणों का सबसे अच्छा IMO है, जहाँ df.loc [2, 1] ['परिणाम'] बहु-स्तंभों को संभालेगा
Michael

यह किसी भी कारण से किसी भी पूर्णांक के साथ काम करता है। जैसेdf.loc[0], df.loc[1]....df.loc[n]
कोडी

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.