2013-03-20 1 views
0

Мне интересно, есть ли какой-либо способ доступа к осям контейнеров pandas (DataFrame, Panel и т. Д.) С помощью определяемого пользователем имени вместо целых или «индексов», столбцов », "minor_axis" и т.д ...ось доступа pandas по пользовательскому имени

Например, с помощью следующего контейнера данных:

df = DataFrame(randn(3,2),columns=['c1','c2'],index=['i1','i2','i3']) 
df.index.name = 'myaxis1' 
df.columns.name = 'myaxis2' 

Я хотел бы сделать это:

df.sum(axis='myaxis1') 
df.xs('c1', axis='myaxis2') # cross section 

Также очень полезно будет:

df.reshape(['myaxis2','myaxis1']) 

(в данном случае не столь актуальна, но она могла бы стать таким, если размер увеличивается)

Причина заключается в том, что я много работаю с многомерными массивами различных размеров, как «время», «переменная», «процентиль» и т. д. ... и тот же фрагмент кода часто применяется к объектам, которые могут быть DataFrame, Panel или даже Panel4D или DataFrame с MultiIndex. На данный момент я часто делаю тест по форме объекта или по общим настройкам скрипта, чтобы узнать, какая ось является релевантной для вычисления суммы или значения. Но я думаю, было бы гораздо удобнее забыть о том, как контейнер реализован в деталях (DataFrame, Panel и т. Д.), И просто подумайте о характере проблемы (скажем, я хочу усреднить за это время, я не хочу думать, работает ли я в «вероятностном» режиме с несколькими процентилями или в «детерминированном» режиме с одним временным рядом).

Написав это сообщение, я обнаружил очень полезный атрибут осей. Приведенный выше код может быть переведен на:

nms = [ax.name for ax in df.axes] 
axid1 = nms.index('myaxis1') 
axid2 = nms.index('myaxis2') 
df.sum(axis=axid1) 
df.xs('c1', axis=axid2) # cross section 

и «перекроить» особенность (не относится к 3-й случай, хотя ...):

newshape = ['myaxis2','myaxis1'] 
axid = [nms.index(nm) for nm in newshape] 
df.swapaxes(*axid) 

Ну, я должен признать, что Я нашел эти решения при написании этого сообщения (и это уже очень удобно), но его можно было бы обобщить для учета DataFrame (или другого) с осями MultiIndex, выполнить поиск по всем осям и меткам ...

По-моему, это было бы существенным улучшением удобства пользователей панд (хорошо, забыв о abo фактическая структура может иметь стоимость исполнения, но пользователь, обеспокоенный производительностью, может быть осторожным в том, как он/она организует данные).

Как вы думаете?

ответ

0

Это еще экспериментальный, но посмотреть на этой странице:

http://pandas.pydata.org/pandas-docs/dev/dsintro.html#panelnd-experimental

import pandas 
import numpy as np 

from pandas.core import panelnd 

MyPanel4D = panelnd.create_nd_panel_factory(
    klass_name = 'MyPanel4D', 
    axis_orders = ['axis4', 'axis3', 'axis2', 'axis1'], 
    axis_slices = {'axis3': 'items', 
        'axis2': 'major_axis', 
        'axis1': 'minor_axis'}, 
    slicer  = 'Panel', 
    stat_axis=2) 
mp4d = MyPanel4D(np.random.rand(5,4,3,2)) 
print mp4d 

Результаты в этом

<class 'pandas.core.panelnd.MyPanel4D'> 
Dimensions: 5 (axis4) x 4 (axis3) x 3 (axis2) x 2 (axis1) 
Axis4 axis: 0 to 4 
Axis3 axis: 0 to 3 
Axis2 axis: 0 to 2 
Axis1 axis: 0 to 1 

Вот нюанс, когда вы его фрагмент, как mp4d[0] вы собираетесь чтобы вернуть панель, если вы не создаете иерархию пользовательских объектов (к сожалению, придется ждать 0.12-dev для поддержки «переименования» Па nel/DataFrame, его нетривиальные и не имеют никаких запросов)

Так что для более тусклых объектов вы можете навязывать свою собственную структуру имен.Ось сглаживание должно работать так, как вы предлагаете, но я думаю, что есть некоторые ошибки

+0

Спасибо, я попробую это. К сожалению, панель в конечном итоге уменьшится до меньшего размерного объекта ... Я рад слышать, что функция запланирована на 0,12! –

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