将Panda DataFrame转换为类似于Panel的结构

时间:2016-02-19 14:15:24

标签: python pandas dataframe panel multi-index

对于将数据重新整理为正确格式的特定问题,我遇到了很多麻烦。

我有这样的数据:

Date           Hour Category Col1 Col2
1/1/10  1:00   1    France   1.1  1.2
1/1/10  2:00   2    France   2.9  1.4
1/1/10  1:00   1    UK       3.8  2.3
2/1/10  1:00   1    France   1.4  1.0
2/1/10  1:00   1    UK       1.1  0.1
2/1/10  2:00   2    UK       1.2  0.4
3/1/10  1:00   1    France   0.5  0.6

我最终需要的是:

  • 每行必须对应一对独特的一对(Category + Hour)
  • 每行包含一个Pd.Series列表(每个Pd.series对应一个日期)。因此,列表的长度对应于与(类别+小时)
  • 匹配的天数
  • 列表的每个元素都是包含其他值的pd.Series对象

(所以,它与3D数组或面板相关,但列表中的元素数量可能会发生变化)

输出将是这样的:

Hour+Category    Lists
1+France         [[1/1/10 1.1 1.2] [2/1/10 1.4 1.0] [3/1/10 0.5 0.6]]
2+France         [[1/1/10 2.9 1.4]]
1+UK             [[1/1/10 3.8 2.3] [2/1/10 1.1 0.1]
2+UK             [[2/1/10 1.2 0.4]]

我的第一次尝试是:

X = X.group_by(['Hour','Category','Date']).first()

这会创建一个多索引,我想这可能有助于重塑。 然后我可以使用

X.to_panel()

创建一个3D面板,但主轴和短轴是小时和类别。 否则我可以尝试

X.unstack(level = 2)

要有一个2D数组,其列为(小时+类别),列之间为(Day + Col1,Day + Col2),然后删除每行中的NA值,并仅保留其余值。

但我仍在努力寻找更好的解决方案。 我也想过这样的事情,但我不能让它发挥作用:

X = X.group_by(['Hour','Category']).apply(lambda x : 
[pd.Series(dict( ???)) ]

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

以下似乎有效(你需要进行一些列重命名等),但是你想要实现的东西对我来说似乎很奇怪 - 将数据作为列表/数组放入一个系列中会让它变得更难稍后使用。

print df.groupby(['Hour', 'Category']).apply(lambda subdf : subdf[['Date','Col1','Col2']].values).reset_index()

   Hour Category                                                  0
0     1   France  [[1/1/10, 1.1, 1.2], [2/1/10, 1.4, 1.0], [3/1/...
1     1       UK           [[1/1/10, 3.8, 2.3], [2/1/10, 1.1, 0.1]]
2     2   France                               [[1/1/10, 2.9, 1.4]]
3     2       UK                               [[2/1/10, 1.2, 0.4]]