将Pandas数据帧转换为频率矩阵

时间:2017-02-27 15:45:11

标签: python pandas matrix

我正在尝试将具有三列(日期,开始,结束)的pandas数据帧转换为频率矩阵。我的输入数据框如下所示:

Date,                Start, End
2016-09-02 09:16:00  18     16
2016-09-02 16:14:10  16      1
2016-09-02 06:17:21  18     17
2016-09-02 05:51:07  23     17
2016-09-02 18:34:44  18     17
2016-09-02 05:44:44  20      4
2016-09-02 09:25:22  18     17
2016-09-02 22:27:44  18     17
2016-09-02 16:02:46   0     18
2016-09-02 15:35:07  17     17
2016-09-02 16:06:42   8     17
2016-09-02 14:47:04  16     23
2016-09-02 07:47:24  20      1
...

“开始”和“结束”的值是023之间的整数。 '日期'是日期时间。我想要创建的频率矩阵是24乘24 csv,其中行i和列j是'结束'= i和'开始'= {的次数{1}}出现在输入中。例如,以上数据将创建:

j

要获得额外帮助,是否可以通过每15分钟创建一个单独矩阵的方式完成?这将是672个矩阵,因为这个日期范围是一周。 我是一个自学成才的初学者,我真的想不出如何用pythonic方式解决这个问题,任何解决方案或建议都会受到高度赞赏。

1 个答案:

答案 0 :(得分:5)

使用简单计数创建矩阵,并将其中一列删除:

mat = df.groupby(['Start', 'End']).count().unstack(level=0)

清理日期级别:

mat.columns = mat.columns.droplevel(0)

现在重新索引行和列并转换为整数:

mat.reindex(*[range(0,24)]*2).fillna(0)

详细说明

首先,计算给定(开始,结束)对出现的出现次数。 groupby对这两列的结果实际上带回了多索引。

df.groupby(['Start', 'End']).count()
Out[134]: 
           Date
Start End      
0     18      1
8     17      1
16    1       1
      23      1
17    17      1
18    16      1
      17      4
20    1       1
      4       1
23    17      1

我们想要的结果是在列中获取Start索引。 unstack这样做:

df.groupby(['Start', 'End']).count().unstack(level=0)
Out[135]: 
      Date                              
Start   0    8    16   17   18   20   23
End                                     
1      NaN  NaN  1.0  NaN  NaN  1.0  NaN
4      NaN  NaN  NaN  NaN  NaN  1.0  NaN
16     NaN  NaN  NaN  NaN  1.0  NaN  NaN
17     NaN  1.0  NaN  1.0  4.0  NaN  1.0
18     1.0  NaN  NaN  NaN  NaN  NaN  NaN
23     NaN  NaN  1.0  NaN  NaN  NaN  NaN

unstack的结果是将Start列作为附加列索引级别移动到当前Date列索引之上(见下文)。这就是我们之后降低等级0的原因。另一种方法 - 取决于您当前的源代码 - 可以是预先过滤Date列,然后unstack将带来一个级别。

_.columns
Out[136]: 
MultiIndex(levels=[['Date'], [0, 8, 16, 17, 18, 20, 23]],
           labels=[[0, 0, 0, 0, 0, 0, 0], [0, 1, 2, 3, 4, 5, 6]],
           names=[None, 'Start'])