2016-06-09 4 views
2

Я пытаюсь работать с пандами мультииндексных dataframe, который выглядит следующим образом:Python Панда: не может сделать ломтик Индексация

    end ref|alt 
chrom start 
chr1 3000714 3000715  T|G 
     3001065 3001066  G|T 
     3001110 3001111  G|C 
     3001131 3001132  G|A 

Я хочу быть в состоянии сделать это:

df.loc[('chr1', slice(3000714, 3001110))] 

Это терпит неудачу со следующей ошибкой:

cannot do slice indexing on with these indexers [1204741] of

df.index.levels[1].dtype возвращается dtype('int64'), так что должен работать с целыми ломтиками вправо?

Кроме того, любые комментарии о том, как это сделать эффективно были бы ценными, так как dataframe имеет 12 миллионов строк, и мне нужно запросить его с таким запросом среза ~ 70 миллионов раз.

ответ

5

Я думаю, что нужно добавить ,: до конца - это значит, что вам нужно нарезка строки, но нужно все столбцы:

print (df.loc[('chr1', slice(3000714, 3001110)),:]) 
        end ref|alt 
chrom start     
chr1 3000714 3000715  T|G 
     3001065 3001066  G|T 
     3001110 3001111  G|C 

Другим решением является добавление axis=0 к loc:

print (df.loc(axis=0)[('chr1', slice(3000714, 3001110))]) 
        end ref|alt 
chrom start     
chr1 3000714 3000715  T|G 
     3001065 3001066  G|T 
     3001110 3001111  G|C 

Но если требуется только 3000714 и 3001110:

print (df.loc[('chr1', [3000714, 3001110]),:]) 
        end ref|alt 
chrom start     
chr1 3000714 3000715  T|G 
     3001110 3001111  G|C 

idx = pd.IndexSlice 
print (df.loc[idx['chr1', [3000714, 3001110]],:]) 
        end ref|alt 
chrom start     
chr1 3000714 3000715  T|G 
     3001110 3001111  G|C 

Timings:

In [21]: %timeit (df.loc[('chr1', slice(3000714, 3001110)),:]) 
1000 loops, best of 3: 757 µs per loop 

In [22]: %timeit (df.loc(axis=0)[('chr1', slice(3000714, 3001110))]) 
1000 loops, best of 3: 743 µs per loop 

In [23]: %timeit (df.loc[('chr1', [3000714, 3001110]),:]) 
1000 loops, best of 3: 824 µs per loop 

In [24]: %timeit (df.loc[pd.IndexSlice['chr1', [3000714, 3001110]],:]) 
The slowest run took 5.35 times longer than the fastest. This could mean that an intermediate result is being cached. 
1000 loops, best of 3: 826 µs per loop 
+0

Фантастические, которые работали отлично. Спасибо за великолепное объяснение. Я также понял, что для моего случая здесь, потому что мой индекс первого уровня был намного меньше второго (в индексе 'level [0]' и 12,6 миллиона в индексе 'level [1]' было 23 элемента), I получил большую скорость, разделив фрейм данных на словарь по первому индексу. На моем полном кадре данных метод 'df.loc (axis = 0) [('chr1', slice (3000714, 3001110))] принимал 218 мс за цикл, тогда как создание словаря и выполнение' dfs ['chr1'] .loc [3000714: 3001110] 'занимает всего 95,7 мкс за цикл. Еще раз спасибо! –

+0

@jezrael, как бы я выбрал dataframe из одного индекса в другой. В этом диапазоне. У меня есть функция, что users.index = np.arange (0, len (users)), это ничего не возвращает ... пользователям. loc [start: end:] пустой dataframe, но users.dataframe имеет контент – Eliethesaiyan

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