我想知道是否有任何方法可以通过用户定义的名称而不是整数或“index”,“columns”,“minor_axis”等来访问pandas容器(DataFrame,Panel等)的轴。
例如,使用以下数据容器:
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甚至是带有MultiIndex的Panel4D或DataFrame。现在,我经常对对象的形状或脚本的一般设置进行测试,以便知道哪个轴是计算总和或平均值的相关轴。但我认为忘记容器在细节中的实现方式会更方便(DataFrame,Panel等......),只需考虑问题的本质(比如我想要平均的时间,我我不想考虑我是在具有几个百分位数的“概率”模式下工作,还是在具有单个时间序列的“确定性”模式下工作。
写这篇文章我(重新)发现了非常有用的axis属性。以上代码可以翻译成:
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-d情况......):
newshape = ['myaxis2','myaxis1']
axid = [nms.index(nm) for nm in newshape]
df.swapaxes(*axid)
好吧,我必须承认我在撰写这篇文章时已经找到了这些解决方案(这已经非常方便了),但它可以推广到使用MultiIndex轴的DataFrame(或其他),对所有搜索轴和标签......
在我看来,这将是对熊猫的用户友好性的一个重大改进(好吧,忘记实际结构可能会有性能成本,但用户担心性能可能会小心他/她如何组织数据)。
您怎么看?
答案 0 :(得分: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]
那样切片时,你将要回到Panel,除非你创建一个自定义对象的层次结构(不幸的是需要等待0.12-dev来支持'重命名' Panel / DataFrame,它的重要性并没有任何要求)
因此,对于更高的暗淡对象,您可以强制使用自己的名称结构。轴 别名应该像你建议的那样工作,但我认为那里有一些错误