10

我正在使用优秀的pandas软件包来处理大量不同的气象诊断数据,当我将数据拼接在一起时,我很快就会用完维度。查看文档,可能是使用MultiIndex可以解决我的问题,但我不确定如何将其应用于我的情况 - 文档显示了使用随机数据和DataFrames 创建 MultiIndexes 的示例,但不是预先存在的 Series时间序列数据。

背景

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

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

最小的公分母是时间序列数据,因此基本结构有一个 pandasSeries对象作为data条目,该metadata字段描述了这些数字的实际含义(例如,东太平洋上空 10 米风的矢量 RMS 误差,用于 24 小时预报实验Test1)。

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

当我遍历这些复合对象时,我有一个iterseries框架iterframes例程和面板例程,当我删除一个维度时重建适当的元数据/数据配对(即来自框架的系列在列之间变化的前置时间将具有所有其父项的元数据加上Lead Time使用从列标签获取的值恢复的字段)。这很好用。

问题

我已经用完了尺寸(使用面板最多为 3-D),并且一旦面板中的所有内容都对齐,我也无法使用诸如dropna删除空列之类的东西(这在绘制摘要统计信息时导致了几个错误)。阅读有关使用具有更高维数据的 pandas 导致阅读有关MultiIndex它及其使用的信息。我已经尝试过文档中给出的示例,但我仍然不清楚如何将其应用于我的情况。任何方向都是有用的。我希望能够:

  • 将基于mySeries的数据合并为沿任意数量维度的多索引DataFrame(这会很棒 - 它会消除一个从系列中创建框架的调用,然后是另一个从框架中创建面板的调用)
  • 遍历生成的 multi-indexed DataFrame,删除单个维度,以便我可以重置组件元数据。

编辑 - 添加代码示例

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

@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 中作为该索引维度的名称。

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

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

1 回答 1

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
于 2012-06-14T17:11:45.560 回答