2013-03-20 6 views
3

Я установки какой-то код, как это:Как индекс в панд MULTINDEX с IX

import pandas as pd 
import numpy as np 
arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'], 
      ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'], 
      ['aaa', 'bbb', 'ccc', 'ccc', 'ddd', 'eee', 'eee', 'eee' ]] 
tuples = zip(*arrays) 
index = pd.MultiIndex.from_tuples(tuples, names=['A', 'B', 'C']) 
df = pd.DataFrame(np.random.randn(8, 4), index=index) 

df 
Out[161]: 
        0   1   2   3 
A B C           
bar one aaa 0.682220 -0.598889 -0.600635 -0.488069 
    two bbb -0.134557 1.614224 -0.191303 0.073813 
baz one ccc -1.006877 -0.137264 -0.319274 1.465952 
    two ccc 0.107222 0.358468 0.165108 -0.258715 
foo one ddd 0.360562 1.759095 -1.385394 -0.646850 
    two eee -1.113520 0.221483 2.226704 -0.994636 
qux one eee -0.609271 -0.888330 0.824189 1.772536 
    two eee -0.008346 -0.688091 0.263303 1.242485 

Я хочу, чтобы найти соответствующие строки на основе комбинации критериев с группами A, B и C.

например в sql условиях: выберите * где A в ('foo', 'qux') и C = 'eee'

Могу ли я получить это с помощью ix? например что-то вроде:

df.ix(['foo', 'qux'],:,'eee') 

Что такое идомальный способ достижения этого для очень больших наборов данных?

(я в настоящее время с помощью панд 0.7, но можно обновить, если это абсолютно необходимо)

+0

Это ломает голову ... ближайший, который я могу получить, это 'df.ix ['foo': 'qux']. Xs ('eee', level = 'C')' – herrfz

+0

... или, может быть, 'df.ix [['foo', 'qux']]. xs ('eee', level = 'C')' – herrfz

ответ

0

As of Pandas 0.14, вы можете передать кортеж селекторов df.loc нарезать мультииндекс:

In [782]: df.loc[(['foo','qux'], slice(None), 'eee'), :] 
Out[782]: 
        0   1   2   3 
A B C           
foo two eee 1.615853 -1.327626 0.772608 -0.406398 
qux one eee 0.472890 0.746417 0.095389 -1.446869 
    two eee 0.711915 0.228739 1.763126 0.558106 
5

Напишу функция делать такого рода вещи в общем:

import numpy as np 
def ms(df, *args): 
    idx = df.index 
    for i, values in enumerate(args): 
     if values is not None: 
      if np.isscalar(values): 
       values = [values] 
      idx = idx.reindex(values, level=i)[0] 
    return df.ix[idx] 

Тогда вы можете сделать это очень легко:

ms(df, ['foo', 'qux'], None, "eee") 
+0

Это действительно здорово. Спасибо. Что означает 'ms'? Как вы относитесь к изменению 'if not isinstance (values, (tuple, list))' to 'if isinstance (values, basestring)'? – unutbu

+1

'ms'' 'MultIndexSelect'. Поскольку значения в индексе могут быть int, float или datetime, в общем случае не проверять только basestring. Я думаю, что лучше использовать 'not isinstance (values, collections.Iterable)', поскольку Pandas может конвертировать итерируемые объекты в Index. – HYRY

+0

Так как str также Iterable, я изменил его на использование 'numpy.isscalar (значения)' – HYRY

Смежные вопросы