首页 > 解决方案 > 为期间之间的每个日期创建一个月并将它们设为列

问题描述

我想在“开始”和“结束”列之间的时间段内分隔每个月,而不是我知道我可以使用 pivot_table 将它们设为列:

subscription|values| start   | end
x           |1     |5/5/2018 |6/5/2018
y           |2     |5/5/2018 |8/5/2018
z           |1     |5/5/2018 |9/5/2018
a           |3     |5/5/2018 |10/5/2018
b           |4     |5/5/2018 |11/5/2018
c           |2     |5/5/2018 |12/5/2018

期望的输出:

subscription|jan| feb | mar | abr | jun | jul | aug | sep | out | nov | dez
x           |   |     |     |     | 1   | 1   |     |     |     |     |
y           |   |     |     |     | 2   | 2   | 2   |     |     |     |
z           |   |     |     |     | 1   | 1   | 1   | 1   |     |     |
a           |   |     |     |     | 3   | 3   | 3   | 3   | 3   |     |
b           |   |     |     |     | 4   | 4   | 4   | 4   | 4   | 4   |
c           |   |     |     |     | 2   | 2   | 2   | 2   | 2   | 2   | 2

标签: pythonpandaspivot-table

解决方案


使用简单pd.Series.cumsum

import calendar
df2 = pd.DataFrame(np.zeros(shape=[len(df),13]), 
                   columns=map(lambda s: calendar.month_abbr[s], 
                                        np.arange(13)))

首先将开始设置为值,并将结束设置为-values

r = np.arange(len(df))
df2.values[r, df.start.dt.month] =  df['values']
df2.values[r, df.end.dt.month]   = -df['values']

然后cumsum通过axis=1 df2 = df2.cumsum(1)

将最终设置为values

df2.values[r, df.end.dt.month]= df['values']

最终输出:

        Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
0   0   0   0   0   0   1   1   0   0   0   0   0   0
1   0   0   0   0   0   2   2   2   2   0   0   0   0
2   0   0   0   0   0   1   1   1   1   1   0   0   0
3   0   0   0   0   0   3   3   3   3   3   3   0   0
4   0   0   0   0   0   4   4   4   4   4   4   4   0
5   0   0   0   0   0   2   2   2   2   2   2   2   2

推荐阅读