0

我想知道是否有任何方法可以通过用户定义的名称而不是整数或“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 等)会更方便,而只是考虑问题的性质(比如说我想随着时间的推移取平均值,我不想考虑我是在具有几个百分位数的“概率”模式下工作,还是在具有单个时间序列的“确定性”模式下工作)。

写这篇文章我已经(重新)发现了非常有用的轴属性。上面的代码可以翻译成:

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(或其他),对所有轴和标签进行搜索...

在我看来,这将是对 pandas 的用户友好性的重大改进(好吧,忘记实际结构可能会产生性能成本,但担心性能的用户可以小心他/她如何组织数据)。

你怎么看?

4

1 回答 1

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 才能支持“重命名”面板/数据帧,这并不重要并且没有任何要求)

因此,对于更暗淡的对象,您可以强加自己的名称结构。轴别名应该像你建议的那样工作,但我认为那里有一些错误

于 2013-03-20T20:47:49.083 回答