python pandas从订阅开始日期和持续时间获取活动订阅者数

问题描述 投票:1回答:1

我有一个pandas数据帧df,其中每行包含start_date(也是索引)和duration(以天为单位)进行订阅。

import pandas as pd    
df = pd.DataFrame({'start_date':['2018-01-01','2018-01-05']})
df['start_date'] = df['start_date'].astype('datetime64[ns]')
df['duration'] = pd.to_timedelta([10,8], unit='D')
df['end_date'] = df['start_date'] + df['duration']

我想绘制一段时间内的订阅者数量。

我的想法是创建另一个数据框架subscribers

active_subscribers = pd.DataFrame({
    'Date': pd.date_range(start=df.index.min(),end=df['end_date'].max()),
    'Number': 0,
})
active_subscribers.set_index('Date', inplace=True)

qazxs指出至少有一个用户处于活动状态的整个时间段。然后我想为每个订阅创建日期范围并将它们添加到Date列,如下所示:

Number

但是这会返回以下错误:

for index, row in df.iterrows(): for this_date in pd.date_range(start=index, end=row['end_date']): active_subscribers[this_date]['Number'] += 1

我希望得到的是一个KeyError: Timestamp('2018-01-01 00:00:00', freq='D')column,看起来像这样:

Number

列qazxswpo表示那天活跃订阅者的数量。

如果您有任何建议,请告诉我

python pandas datetime date-range
1个回答
0
投票

您可以使用Date Number 2018-01-01 1 2018-01-02 1 2018-01-03 1 2018-01-04 1 2018-01-05 2 2018-01-06 2 2018-01-07 2 2018-01-08 2 2018-01-09 2 2018-01-10 2 2018-01-11 1 2018-01-12 1 2018-01-13 1 的列表理解为新的Number,然后通过itertuplesDataFrame获取新列:

groupby

它更快,因为size解决方案:

df = pd.DataFrame(index=pd.to_datetime(['2018-01-01','2018-01-05']))
df['duration'] = pd.to_timedelta([10,8], unit='D')
df['end_date'] = df.index + df['duration']
print (df)
           duration   end_date
2018-01-01  10 days 2018-01-11
2018-01-05   8 days 2018-01-13

df = df.rename_axis('start_date').reset_index()
com = [pd.Series(r.Index,pd.date_range(r.start_date, r.end_date)) for r in df.itertuples()]
df1 = pd.concat(com).reset_index()
df1.columns=['Date','Number']
df1 = df1.groupby('Date')['Number'].size().reset_index()
print (df1)
         Date  Number
0  2018-01-01       1
1  2018-01-02       1
2  2018-01-03       1
3  2018-01-04       1
4  2018-01-05       2
5  2018-01-06       2
6  2018-01-07       2
7  2018-01-08       2
8  2018-01-09       2
9  2018-01-10       2
10 2018-01-11       2
11 2018-01-12       1
12 2018-01-13       1

样品:

iterrows

功能:

In [288]: %timeit (iterrows_sol(df))
10 loops, best of 3: 51.1 ms per loop

In [289]: %timeit (itertupl_sol(df))
100 loops, best of 3: 10.2 ms per loop
© www.soinside.com 2019 - 2024. All rights reserved.