熊猫:日期范围的汇总,包含开始日期和结束日期

时间:2020-02-19 15:06:59

标签: python pandas dataframe

我正在尝试创建一个DataFrame,以便可以分析某个时间段内uID处于活动状态的频率。

我有一个输入DataFrame,如下所示:

uID   startdate     stopdate      active_sub
1    01-01-2019     31-01-2019    1
2    01-02-2019     31-12-2019    1
1    15-01-2019     31-12-2019    1
3    01-06-2019     31-11-2019    1

我要实现的目标是为每个DataFrameDate获得一个uID,每个用户的有效订阅总和。

Date        uID:1  uID:2  uID:3 
01-01-2019  1      0      0
02-01-2019  1      0      0
03-01-2019  1      0      0 
...
15-01-2019  2      0      0   #uID:1  has 2 active subcriptions on this day
...
31-12-2019  1      1      1

我有以下有效的代码,但不适用于重复的uID。输入数据集很大,并且有很多重复的uID。

#Create date dataframe
df = pd.DataFrame(
    index = pd.date_range('01-01-2019', '31-12-2019').normalize(),
    columns = input_df['uID']
)

for row in input_df.iterrows():
    df[row[1][0]].loc[row[1][1]] = 1 #StartDate
    df[row[1][0]].loc[row[1][2]] = 0 #EndDate
    df[row[1][0]] = df[row[1][0]].fillna(method= 'ffill')

df = df.fillna(0)

是否有可能快速修复,或者有其他方法可以快速实现所需的数据帧吗?

1 个答案:

答案 0 :(得分:0)

首先,请注意,日期"31-11-2019"根本不存在:-) 但是,在纠正此错误之后,也许这是必须要做的:

from io import StringIO
import pandas as pd
data = (
'uID   startdate     stopdate      active_sub\n'
'1    01-01-2019     31-01-2019    1\n'
'2    01-02-2019     31-12-2019    1\n'
'1    15-01-2019     31-12-2019    1\n'
'3    01-06-2019     30-11-2019    1\n')

df = pd.read_fwf(StringIO(data))

df['startdate'] = pd.to_datetime(df['startdate'], format='%d-%m-%Y')
df['stopdate'] = pd.to_datetime(df['stopdate'], format='%d-%m-%Y')
df['uID'] = df['uID'].astype(str)


df_result = df.apply(lambda x: pd.Series(x['uID'], 
                             index=pd.date_range(x['startdate'].floor('D'), 
                                                 x['stopdate'].ceil('D'), 
                                                 freq='D')), axis=1)\
  .stack().str.get_dummies().reset_index(level=0, drop=True)

df_result2 = df_result.groupby(df_result.index).agg(sum)