Фильтр фрейма данных с мультииндексом: возвращает все строки на верхнем уровне индекса с заданными значениями - PullRequest
0 голосов
/ 01 января 2019

Я ищу синтаксис для возврата всех данных первого уровня с учетом нескольких критериев конечного значения.Я читал и находил решения для фильтрации с помощью .loc или .xs, но я вполне могу получить синтаксис для того, что я хочу.Я использую для работы с xpath, и я просто хочу //A[ B [ @x=1 and @y=2]] по существу.

Я пробовал много перестановок синтаксиса, я знаком с использованием форм df.loc df.xs mutlti [],немного с df.index.get_level_values ​​() и т. д. *

Итак, с таким фреймом данных: x y A B a b <strong>1 2</strong> a f 4 5 a c 3 4 b d 1 5<br> b c 1 2 c d <strong>2 3</strong>

Я хочу найти определенную комбинацию из x и y и вернутьвсе строки на уровне индекса А.

Итак, я хочу, чтобы x = 1 и y = 2, и получить

x y A B a b <strong>1 2</strong> a f <strong>4 5</strong> a c <strong>3 4</strong> b d <strong>1 5</strong> b c <strong>1 2</strong>

Поскольку по крайней мере 1 строка данногоA соответствует

И еще более общим решением было бы поиск значения x определенного B и значения y определенного другого B.

(пытаясь прояснить ситуацию):Я имею в виду, что вместо значений конечного уровня, которые я ищу, меня может заинтересовать комбинация только определенных значений B.Ниже у меня есть B 1 = b и x = 3.поэтому я смешиваю совпадение значения со значением индекса.Тогда как раньше я ограничил два конечных значения.Опять же, я представляю это в xpath как //A[ B [ local-name() == b and @x=3] and B[ local-name() == f and @y=5] ] (думаю, я понял это правильно).

Например, B 1 = b: x = 3 и B 2 = f: y = 5.Возвращение:

x y A B a <strong>b</strong> <strong>1</strong> 2 a <strong>f</strong> 4 <strong>5</strong> a c 3 4

Спасибо!

Ответы [ 3 ]

0 голосов
/ 01 января 2019

Вы можете использовать groupby на уровне = 'A' и filter после создания столбца flag для каждого столбца x и y, если вы ищете значенияв нем с numpy.where.

#using @jpp setup
import numpy as np
df['flagx'] = np.where(df.x == 1,1,0)
df['flagy'] = np.where(df.y == 5,1,0)

Теперь, если вы хотите, чтобы и x, и y удовлетворяли условию для любого значения B и того же A, вы можете использовать any для каждого флага и искать оба с &:

print (df.groupby(level='A').filter(lambda dfg: dfg.flagx.any() & dfg.flagy.any() )
         .drop(['flagx','flagy'],axis=1))
     x  y
A B      
a b  1  2
  f  4  5
  c  3  4
b d  1  5
  c  1  2

Если вы хотите, чтобы оба условия на x и y выполнялись в одной строке, то вы можете сделать это, изменив положение any и & в filter:

print (df.groupby(level='A').filter(lambda dfg: (dfg.flagx & dfg.flagy).any() )
         .drop(['flagx','flagy'],axis=1))
     x  y
A B      
b d  1  5
  c  1  2
0 голосов
/ 01 января 2019

Использование groupby + transform + any

df[df.eq({'x':1,'y':2}).groupby(level=0).transform('any').any(1)]
     x  y
A B      
a b  1  2
  f  4  5
  c  3  4
b d  1  5
  c  1  2
0 голосов
/ 01 января 2019

Вы можете query ваш фрейм данных с помощью пары шагов:

A_idx = df.query('x == 1 & y == 2').index.get_level_values('A')
res = df.query('A in @A_idx')

print(res)

#      x  y
# A B      
# a b  1  2
#   f  4  5
#   c  3  4
# b d  1  5
#   c  1  2

Настройка

df = pd.DataFrame([['a', 'b', 1, 2], ['a', 'f', 4, 5], ['a', 'c', 3, 4],
                   ['b', 'd', 1, 5], ['b', 'c', 1, 2], ['c', 'd', 2, 3]],
                  columns=['A', 'B', 'x', 'y'])

df = df.set_index(['A', 'B'])
...