C1 | C2 | C3 | C4 |
---|---|---|---|
A | 12 | True | 89 |
9 | False | 77 | |
5 | True | 23 | |
B | 9 | True | 45 |
5 | True | 45 | |
2 | False | 78 | |
C | 11 | True | 10 |
8 | False | 08 | |
12 | False | 09 |
C1 & C2 are the multi index. I'm hoping to get a result which gives me only values in C1 which have values both lower than 10 and greater than or equal to 10 in C2.
So in the table above C1 - B should go, with the final result should look like this:
C1 | C2 | C3 | C4 |
---|---|---|---|
A | 12 | True | 89 |
9 | False | 77 | |
5 | True | 23 | |
C | 11 | True | 10 |
8 | False | 08 | |
12 | False | 09 |
I tried df.loc[(df.C2 < 10 ) & (df.C2 >= 10)] but this didn't work.
I also tried:
filter1 = df.index.get_level_values('C2') < 10 filter2 = df.index.get_level_values('C2') >= 10
df.iloc[filter1 & filter2]
Which I saw suggested on another post that also didn't work. Any one know how to solve this? Thanks
You can slice a MultiIndex by providing multiple indexers. You can provide any of the selectors as if you are indexing by label, see Selection by Label, including slices, lists of labels, labels, and boolean indexers. You can use slice(None) to select all the contents of that level.
Use GroupBy.transform
with GroupBy.any
for test at least one condition match per groups, so possible last filter by m
DataFrame:
filter1 = df.index.get_level_values('C2') < 10
filter2 = df.index.get_level_values('C2') >= 10
m = (df.assign(filter1= filter1, filter2=filter2)
.groupby(level=0)[['filter1','filter2']]
.transform('any'))
print (m)
filter1 filter2
C1 C2
A 12 True True
9 True True
5 True True
B 9 True False
5 True False
2 True False
C 11 True True
8 True True
12 True True
df = df[m.filter1 & m.filter2]
print (df)
C3 C4
C1 C2
A 12 True 89
9 False 77
5 True 23
C 11 True 10
8 False 8
12 False 9
Alternative solution:
filter1 = df.index.get_level_values('C2') < 10
filter2 = df.index.get_level_values('C2') >= 10
lvl1 = df.index[filter1].remove_unused_levels().levels[0]
lvl2 = df.index[filter2].remove_unused_levels().levels[0]
df1 = df.loc[set(lvl1).intersection(lvl2)]
print (df1)
C3 C4
C1 C2
A 12 True 89
9 False 77
5 True 23
C 11 True 10
8 False 8
12 False 9
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With