如何将我的pandas数据分组推广到3个以上的维度?

时间:2012-06-14 16:58:42

标签: python pandas

我正在使用优秀的pandas软件包来处理大量不同的气象诊断数据,而且当我将数据拼接在一起时,我很快就会耗尽尺寸。查看文档,可能是使用MultiIndex可能会解决我的问题,但我不确定如何将其应用于我的情况 - 文档显示了使用随机数据创建MultiIndexes的示例{{1} } s,但不包含具有预先存在的时间序列数据的系列。

背景

我使用的基本数据结构包含两个主要字段:

  • DataFrame,这是一个字典,由描述数字
  • 的键值对组成
  • metadata,这是一个包含数字本身的pandas数据结构。

最小公分母是时间序列数据,因此基本结构有一个pandas data对象作为Series条目,而data字段描述了这些数字实际上是什么(例如vector东太平洋10米风的RMS误差,通过实验测试1)进行24小时预测。

我正在考虑采用最低通用分母并将各种时间序列粘合在一起,以使结果更有用,并允许轻松组合。例如,我可能想要查看所有不同的提前期 - 我有一个过滤器例程,它将占用我的时间序列共享相同的元数据条目以用于提前期(例如实验,区域等)。并返回一个新对象,其中metadata字段仅包含公共条目(即已删除metadata),现在Lead Time字段为panda dataDataFrame值给出的列标签。我可以再次对此进行扩展,并说我想获取结果帧并将它们组合在一起,只有另一个不同的条目(例如Lead Time)给我一只大熊猫Experiment。对于我的条目,其中项目索引由组成框架中的Panel元数据值给出,而对象的新元数据不包含ExperimentLead Time

当我迭代这些复合对象时,我有一个Experiment例程用于框架,iterseries例程用于面板重建适当的元数据/数据配对,因为我删除了一个维度(即系列从具有不同列的提前期的帧中,将具有其父加上的所有元数据,iterframes字段将使用从列标签获取的值进行恢复。这很有效。

问题

我已经用完了维度(最多使用Panel 3-D)并且我也无法使用Lead Time之类的东西在Panel中对齐所有内容后删除空列(这有在绘制汇总统计数据时导致了一些错误)。阅读有关使用具有更高维度数据的pandas已经阅读了有关dropna及其使用的内容。我已经尝试过文档中给出的示例,但是我仍然有点不清楚如何将它应用到我的情况中。任何方向都会有用。我希望能够:

  • 将基于MultiIndex的数据与任意数量维度的多索引Series相结合(这会很棒 - 它会消除一次调用以从系列中创建帧,然后另一个从框架创建面板)
  • 对生成的多索引DataFrame进行迭代,删除单个维度,以便重置组件元数据。

修改 - 添加代码示例

Wes McKinney在下面的回答几乎正是我所需要的 - 问题在于我从系列支持的存储对象的初始翻译,一旦我开始将元素组合在一起,我必须使用我的DataFrame支持的对象。 Data-Frame支持的类具有以下方法,该方法接收基于系列的对象的列表以及将在列之间变化的元数据字段。

DataFrame

一旦我有了这个例程给出的框架,我就可以轻松地应用下面建议的各种操作 - 特别是当我使用@classmethod def from_list(cls, results_list, column_key): """ Populate object from a list of results that all share the metadata except for the field `column_key`. """ # Need two copies of the input results - one for building the object # data and one for building the object metadata for_data, for_metadata = itertools.tee(results_list) self = cls() self.column_key = column_key self.metadata = next(for_metadata).metadata.copy() if column_key in self.metadata: del self.metadata[column_key] self.data = pandas.DataFrame(dict(((transform(r[column_key]), r.data) for r in for_data))) return self 字段时能够使用names字段 调用concat - 这消除了在内部存储列键名称的需要 因为它作为索引维度的名称存储在MultiIndex中。

我希望能够实现下面的解决方案,只需获取匹配的Series支持的类列表和键列表,然后按顺序进行分组。但是,我不知道列将提前代表什么,所以:

  • 将系列数据存储在1-D DataFrame
  • 中对我来说真的没有意义
  • 我没有看到如何设置索引的名称和初始系列中的列 - >帧分组

1 个答案:

答案 0 :(得分:10)

我可能会建议使用pandas.concat及其keys参数将Series DataFrames粘合在一起,以便在列中创建MultiIndex:

In [20]: data
Out[20]: 
{'a': 2012-04-16    0
2012-04-17    1
2012-04-18    2
2012-04-19    3
2012-04-20    4
2012-04-21    5
2012-04-22    6
2012-04-23    7
2012-04-24    8
2012-04-25    9
Freq: D,
 'b': 2012-04-16    0
2012-04-17    1
2012-04-18    2
2012-04-19    3
2012-04-20    4
2012-04-21    5
2012-04-22    6
2012-04-23    7
2012-04-24    8
2012-04-25    9
Freq: D,
 'c': 2012-04-16    0
2012-04-17    1
2012-04-18    2
2012-04-19    3
2012-04-20    4
2012-04-21    5
2012-04-22    6
2012-04-23    7
2012-04-24    8
2012-04-25    9
Freq: D}

In [21]: df = pd.concat(data, axis=1, keys=['a', 'b', 'c'])

In [22]: df
Out[22]: 
            a  b  c
2012-04-16  0  0  0
2012-04-17  1  1  1
2012-04-18  2  2  2
2012-04-19  3  3  3
2012-04-20  4  4  4
2012-04-21  5  5  5
2012-04-22  6  6  6
2012-04-23  7  7  7
2012-04-24  8  8  8
2012-04-25  9  9  9

In [23]: df2 = pd.concat([df, df], axis=1, keys=['group1', 'group2'])

In [24]: df2
Out[24]: 
            group1        group2      
                 a  b  c       a  b  c
2012-04-16       0  0  0       0  0  0
2012-04-17       1  1  1       1  1  1
2012-04-18       2  2  2       2  2  2
2012-04-19       3  3  3       3  3  3
2012-04-20       4  4  4       4  4  4
2012-04-21       5  5  5       5  5  5
2012-04-22       6  6  6       6  6  6
2012-04-23       7  7  7       7  7  7
2012-04-24       8  8  8       8  8  8
2012-04-25       9  9  9       9  9  9

你有:

In [25]: df2['group2']
Out[25]: 
            a  b  c
2012-04-16  0  0  0
2012-04-17  1  1  1
2012-04-18  2  2  2
2012-04-19  3  3  3
2012-04-20  4  4  4
2012-04-21  5  5  5
2012-04-22  6  6  6
2012-04-23  7  7  7
2012-04-24  8  8  8
2012-04-25  9  9  9

甚至

In [27]: df2.xs('b', axis=1, level=1)
Out[27]: 
            group1  group2
2012-04-16       0       0
2012-04-17       1       1
2012-04-18       2       2
2012-04-19       3       3
2012-04-20       4       4
2012-04-21       5       5
2012-04-22       6       6
2012-04-23       7       7
2012-04-24       8       8
2012-04-25       9       9

你可以任意多个级别:

In [29]: pd.concat([df2, df2], axis=1, keys=['tier1', 'tier2'])
Out[29]: 
             tier1                       tier2                    
            group1        group2        group1        group2      
                 a  b  c       a  b  c       a  b  c       a  b  c
2012-04-16       0  0  0       0  0  0       0  0  0       0  0  0
2012-04-17       1  1  1       1  1  1       1  1  1       1  1  1
2012-04-18       2  2  2       2  2  2       2  2  2       2  2  2
2012-04-19       3  3  3       3  3  3       3  3  3       3  3  3
2012-04-20       4  4  4       4  4  4       4  4  4       4  4  4
2012-04-21       5  5  5       5  5  5       5  5  5       5  5  5
2012-04-22       6  6  6       6  6  6       6  6  6       6  6  6
2012-04-23       7  7  7       7  7  7       7  7  7       7  7  7
2012-04-24       8  8  8       8  8  8       8  8  8       8  8  8
2012-04-25       9  9  9       9  9  9       9  9  9       9  9  9