Saya memiliki bingkai data multi-indeks dengan kolom 'A' dan 'B'.
Apakah ada cara untuk memilih baris dengan memfilter pada satu kolom multi-indeks tanpa menyetel ulang indeks ke indeks satu kolom?
Sebagai contoh.
# 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]
python
pandas
dataframe
multi-index
peredam suara
sumber
sumber
Jawaban:
Salah satu caranya adalah dengan menggunakan
get_level_values
metode Indeks: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
Dalam 0.13 Anda akan dapat menggunakan
xs
dengandrop_level
argumen :df.xs(1, level='A', drop_level=False) # axis=1 if columns
Catatan: jika ini adalah kolom MultiIndex daripada indeks, Anda dapat menggunakan teknik yang sama:
In [21]: df1 = df.T In [22]: df1.iloc[:, df1.columns.get_level_values('A') == 1] Out[22]: A 1 B 4 0 1
sumber
Anda juga dapat menggunakan
query
yang sangat mudah dibaca menurut saya dan langsung digunakan: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
Untuk apa yang ada dalam pikiran Anda, Anda sekarang dapat melakukan:
df.query('A == 1') C A B 1 10 6
Anda juga dapat memiliki kueri yang lebih kompleks menggunakan
and
df.query('A >= 1 and B >= 50') C A B 3 50 8 4 80 9
dan
or
df.query('A == 1 or B >= 50') C A B 1 10 6 3 50 8 4 80 9
Anda juga dapat melakukan kueri pada tingkat indeks yang berbeda , misalnya
df.query('A == 1 or C >= 8')
akan kembali
C A B 1 10 6 3 50 8 4 80 9
Jika Anda ingin menggunakan variabel di dalam kueri Anda
@
, Anda dapat menggunakan :b_threshold = 20 c_threshold = 8 df.query('B >= @b_threshold and C <= @c_threshold') C A B 2 20 7 3 50 8
sumber
df.query('A == 1 or C >= 8')
df.query()
berfungsi dengan baik dengan variabel jika mereka dirujuk dengan '@' di dalam ekspresi dalam kueri, misalnyadf.query('A == @var
) untuk variabelvar
di lingkungan.Anda dapat menggunakan
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
Jika Anda ingin mempertahankan
A
level (drop_level
argumen kata kunci hanya tersedia mulai dari 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
sumber
Memahami cara mengakses pandas multi-indeks DataFrame dapat membantu Anda dengan semua jenis tugas seperti itu.
Salin tempel ini di kode Anda untuk menghasilkan contoh:
# 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
Akan memberi Anda tabel seperti ini:
Akses standar menurut kolom
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
Akses berdasarkan baris
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
Mengiris multi-indeks
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
sumber
ValueError: cannot handle a non-unique multi-index!
kesalahanAnda dapat menggunakan
DataFrame.loc
:>>> df.loc[1]
Contoh
>>> 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
sumber
df.loc[0], df.loc[1]....df.loc[n]
Pilihan lainnya adalah:
filter1 = df.index.get_level_values('A') == 1 filter2 = df.index.get_level_values('B') == 4 df.iloc[filter1 & filter2] Out[11]: 0 A B 1 4 1
sumber