从 Pandas 中的 MultiIndex 创建数据框

Posted

技术标签:

【中文标题】从 Pandas 中的 MultiIndex 创建数据框【英文标题】:Create a dataframe from a MultiIndex in pandas 【发布时间】:2021-06-14 22:00:20 【问题描述】:

这是我第一次使用 .h5 格式的数据集,我使用下面的代码将键分配给新变量

# Assign every meter to a variable  
house3_aggregate = ukdale.get('/building3/elec/meter1')
house3_kettle = ukdale.get('/building3/elec/meter2')
house3_electric_heater = ukdale.get('/building3/elec/meter3')
house3_laptop = ukdale.get('/building3/elec/meter4')
house3_projector = ukdale.get('/building3/elec/meter5')

打印第一个变量会给我以下结构:

print(house3_aggregate)

physical_quantity           power
type                        apparent
2013-02-27 20:35:14+00:00   5.0
2013-02-27 20:35:20+00:00   4.0
2013-02-27 20:35:26+00:00   5.0
2013-02-27 20:35:32+00:00   5.0
2013-02-27 20:35:38+00:00   4.0
... ...
2013-04-08 06:14:22+01:00   168.0
2013-04-08 06:14:28+01:00   171.0
2013-04-08 06:14:34+01:00   176.0
2013-04-08 06:14:40+01:00   174.0
2013-04-08 06:14:53+01:00   3122.0
512327 rows × 1 columns

使用 .columns 更好地了解我在这里看到的内容后,我得到以下输出:

MultiIndex([('power', 'apparent')],
           names=['physical_quantity', 'type'])

我想将此数据集转换为只有两列的数据集,像这样

Timestamp                   Energy Consumption
2013-02-27 20:35:14+00:00   5.0
2013-02-27 20:35:20+00:00   4.0
2013-02-27 20:35:26+00:00   5.0
2013-02-27 20:35:32+00:00   5.0
2013-02-27 20:35:38+00:00   4.0
... ...
2013-04-08 06:14:22+01:00   168.0
2013-04-08 06:14:28+01:00   171.0
2013-04-08 06:14:34+01:00   176.0
2013-04-08 06:14:40+01:00   174.0
2013-04-08 06:14:53+01:00   3122.0
512327 rows × 1 columns

我找到了this 的帖子,并尝试像这样实现代码

house3_aggregate = house3_aggregate.reset_index()
print(house3_aggregate)

这给了我以下输出

physical_quantity                     index    power
type                                        apparent
0                 2013-02-27 20:35:14+00:00      5.0
1                 2013-02-27 20:35:20+00:00      4.0
2                 2013-02-27 20:35:26+00:00      5.0
3                 2013-02-27 20:35:32+00:00      5.0
4                 2013-02-27 20:35:38+00:00      4.0
...                                     ...      ...
512322            2013-04-08 06:14:22+01:00    168.0
512323            2013-04-08 06:14:28+01:00    171.0
512324            2013-04-08 06:14:34+01:00    176.0
512325            2013-04-08 06:14:40+01:00    174.0
512326            2013-04-08 06:14:53+01:00   3122.0

[512327 rows x 2 columns]

除了命名错误的列之外,这似乎是我需要的。预计当我再次调用 .column 时,数据似乎仍然是 MultiIndex

house3_aggregate.columns
MultiIndex([('index',         ''),
            ('power', 'apparent')],
           names=['physical_quantity', 'type'])

我也尝试了this 方法并使用了下面的代码

house3_aggregate = house3_aggregate.to_frame()
print(house3_aggregate)

这给了我以下错误

AttributeError: 'DataFrame' object has no attribute 'to_frame'

我现在很困惑,因为这个错误使数据看起来像是二维的。关于我应该做些什么来摆脱 Multindex 并将数据转换为如下所示的二维数据框中的任何想法?最终我想使用 pd.concat 将所有变量合并到 house3 的单个数据集中

Timestamp                   Energy Consumption
2013-02-27 20:35:14+00:00   5.0
2013-02-27 20:35:20+00:00   4.0
2013-02-27 20:35:26+00:00   5.0
2013-02-27 20:35:32+00:00   5.0
2013-02-27 20:35:38+00:00   4.0
... ...
2013-04-08 06:14:22+01:00   168.0
2013-04-08 06:14:28+01:00   171.0
2013-04-08 06:14:34+01:00   176.0
2013-04-08 06:14:40+01:00   174.0
2013-04-08 06:14:53+01:00   3122.0
512327 rows × 1 columns

【问题讨论】:

【参考方案1】:

一个DataFrame由三部分组成:索引、列和值。您可以在 DataFrame 中看到:

Out[31]: 
physical_quantity            power
type                      apparent
2013-02-27 20:35:14+00:00         
2013-02-27 20:35:20+00:00      4.0
2013-02-27 20:35:26+00:00      5.0
2013-02-27 20:35:32+00:00      5.0
2013-02-27 20:35:38+00:00      4.0

In [38]: df.index
Out[38]: 
Index(['2013-02-27 20:35:20+00:00', '2013-02-27 20:35:26+00:00',
       '2013-02-27 20:35:32+00:00', '2013-02-27 20:35:38+00:00'],
      dtype='object', name='index')

In [34]: df.columns
Out[34]: 
MultiIndex([('power', 'apparent')],
           names=['physical_quantity', 'type'])


In [32]: df.values
Out[32]: 
array([[4.],
       [5.],
       [5.],
       [4.]])

只要大小保持一致,您就可以随意设置其中的每一个。索引必须与行数一样大,列必须与列数相对应。

Multiindex 只包含每个列值的元组。如果您希望能够轻松选择 DataFrame 的子集,这可能非常有用。

您想覆盖列名。首先,为了“查看”索引名称(在我的示例中我设置为 'index'),您可以使用 reset_index

In [39]: df = df.reset_index()
Out[39]: 
physical_quantity                     index    power
type                                        apparent
0                  2013-02-27 20:35:20+0...      4.0
1                  2013-02-27 20:35:26+0...      5.0
2                  2013-02-27 20:35:32+0...      5.0
3                  2013-02-27 20:35:38+0...      4.0

In [41]: df.columns
Out[41]: 
MultiIndex([('index',         ''),
            ('power', 'apparent')],
           names=['physical_quantity', 'type'])

如您所见,列的长度现在是 2。现在您可以用

覆盖它
In [42]: df.columns = ['Timestamp', 'Energy Consumption']

In [43]: df
Out[43]: 
                  Timestamp  Energy Consumption
0  2013-02-27 20:35:20+0...                 4.0
1  2013-02-27 20:35:26+0...                 5.0
2  2013-02-27 20:35:32+0...                 5.0
3  2013-02-27 20:35:38+0...                 4.0

【讨论】:

以上是关于从 Pandas 中的 MultiIndex 创建数据框的主要内容,如果未能解决你的问题,请参考以下文章

使用元组键从字典创建 MultiIndex pandas DataFrame

将 MultiIndex DataFrame 格式从列排序到 Pandas 中的变量

根据条件获取pandas multiindex中的索引值

6种方式创建多层索引MultiIndex

Pandas:从 DataFrame 分配 MultiIndex 列

使用 pandas 创建一个 multiIndex