Pandas 时间序列数据 - 每 30 分钟计算过去 24 小时内的唯一值
Pandas timeseries data - counting unique values during past 24 hours every 30 minutes
我正在尝试根据每条消息的数据来衡量论坛上的消息 activity。
为此,我想知道有多少 unique/different 作者在过去 24 小时内 post 编辑了消息,每 [=51] =] (9:00, 9:30, 10:00, ...).
我有一个pandas DataFrame
来记录消息信息。一条消息有一个 post 编号、post 发布时间以及发件人。这是我的一些数据:
>>> # import pandas as pd
>>> # here df is a pd.DataFrame
>>> print df.loc[:, ['Message Timestamp','Message Author']]
Post# Message Timestamp Message Author
239257 2017-06-09 14:45:46-04:00 JTTLJTTLFBVTNJDF
239258 2017-06-09 14:09:51-04:00 Tvpfrnpvb22
239259 2017-06-09 13:54:13-04:00 Hpzb Tbxb
239260 2017-06-09 13:45:37-04:00 TbnFrbnTrbdfr
239261 2017-06-09 13:28:55-04:00 JTTLJTTLFBVTNJDF
239262 2017-06-09 13:20:23-04:00 njlftlj84
239263 2017-06-09 13:19:59-04:00 TbnFrbnTrbdfr
239264 2017-06-09 13:19:23-04:00 Vjtb Npvb Ttpdlt
239265 2017-06-09 13:15:03-04:00 njlftlj84
239266 2017-06-09 13:06:07-04:00 vndpnnpndfntt
239267 2017-06-09 12:48:54-04:00 TbnFrbnTrbdfr
239268 2017-06-09 12:16:59-04:00 Hrffn n Hpld
239269 2017-06-09 12:06:12-04:00 Xbllfr
239270 2017-06-09 11:27:33-04:00 TbttppfdTrbdfrFrz
239271 2017-06-09 11:21:46-04:00 ND`jn`BjhD
239272 2017-06-09 11:19:34-04:00 TbnFrbnTrbdfr
239273 2017-06-09 10:55:01-04:00 bbndpntfbdfll
239274 2017-06-09 10:55:01-04:00 JTTLJTTLFBVTNJDF
................(continued for years).................
例如,使用上述数据,我们看到用户“JTTLJTTLFBVTNJDF”在过去二十四小时内至少 post 编辑了三次;那个人只为 "number of unique authors in the last twenty four hours" 贡献了 1
。
所需的输出如下所示(取决于之前 24 小时的数据):
>>> print some_function(df, past='24 hours', every='30 mins')
Index Number_of_unique_authors_in_the_last_24_hours
2017-06-09 15:00:00-04:00 12
2017-06-09 14:30:00-04:00 11
2017-06-09 14:00:00-04:00 13
...(and so forth)......
为清楚起见,这是在 15:00 说的,有 12 个 不同的 人在上次 twenty-four 中 post 编辑了消息小时,基于数据。
我尝试了 pd.Timestamp.ceil
、groupby
和 rolling
的不同组合,但没有接近我想要的。有经验的人可能知道正确的事情组合。
此外,如果有人有更好的标题想法,请告诉我。
编辑:我有点惊讶像下面这样的东西不起作用。
series = df.set_index('Message Timestamp')['Message Author']
series.resample('30 min').rolling('1D').nunique() #not supported
我知道如何让 for-loop 做我想做的事,但如果能找到 pandas-powered 做事的方式就好了。
我没能想出一些优雅的解决方案,而是通过循环遍历数据框来提出一个残酷的解决方案,希望如果您的数据集不是很大,这会起作用:
time, unique_count = [], []
for i in range(len(df)):
time.append(t)
t = df.ix[i, 'Time']
#get the datetime of 24 hours ago
yesterday = t - timedelta(days=1)
#filter the original dataframe and count unique authors
count = len(df.ix[(df['Time']<=t) &
(df['Time']>=yesterday),'Author'].unique())
unique_count.append(count)
result = pd.DataFrame({'Time': time,
'Number_of_unique_authors':unique_count})
等待有人想出更优雅的解决方案。
考虑resample
to aggregate to 30 minute intervals and then run nunique
。然后 运行 a transform
每 24 小时有条件地聚合新的唯一计数列。您需要先将时间戳设置为重新采样的索引,然后再设置为常规列以聚合到 24 小时。
import datetime
import pandas as pd
...
df = df[['Message Timestamp', 'Message Author']]
df['24-HourCount'] = df.transform(lambda x:\
len(df[(df['Message Timestamp'].between(x['Message Timestamp'] - datetime.timedelta(days=1),
x['Message Timestamp']))]['Message Author'].unique()), axis=1)
df = df.set_index('Message Timestamp')
df = df[['24-HourCount']].resample('30T').max()
print(df)
# 24-HourCount
# Message Timestamp
# 2017-06-09 14:30:00 2.0
# 2017-06-09 15:00:00 5.0
# 2017-06-09 15:30:00 NaN
# 2017-06-09 16:00:00 7.0
# 2017-06-09 16:30:00 7.0
# 2017-06-09 17:00:00 10.0
# 2017-06-09 17:30:00 11.0
# 2017-06-09 18:00:00 12.0
# 2017-06-09 18:30:00 12.0
我正在尝试根据每条消息的数据来衡量论坛上的消息 activity。
为此,我想知道有多少 unique/different 作者在过去 24 小时内 post 编辑了消息,每 [=51] =] (9:00, 9:30, 10:00, ...).
我有一个pandas DataFrame
来记录消息信息。一条消息有一个 post 编号、post 发布时间以及发件人。这是我的一些数据:
>>> # import pandas as pd
>>> # here df is a pd.DataFrame
>>> print df.loc[:, ['Message Timestamp','Message Author']]
Post# Message Timestamp Message Author
239257 2017-06-09 14:45:46-04:00 JTTLJTTLFBVTNJDF
239258 2017-06-09 14:09:51-04:00 Tvpfrnpvb22
239259 2017-06-09 13:54:13-04:00 Hpzb Tbxb
239260 2017-06-09 13:45:37-04:00 TbnFrbnTrbdfr
239261 2017-06-09 13:28:55-04:00 JTTLJTTLFBVTNJDF
239262 2017-06-09 13:20:23-04:00 njlftlj84
239263 2017-06-09 13:19:59-04:00 TbnFrbnTrbdfr
239264 2017-06-09 13:19:23-04:00 Vjtb Npvb Ttpdlt
239265 2017-06-09 13:15:03-04:00 njlftlj84
239266 2017-06-09 13:06:07-04:00 vndpnnpndfntt
239267 2017-06-09 12:48:54-04:00 TbnFrbnTrbdfr
239268 2017-06-09 12:16:59-04:00 Hrffn n Hpld
239269 2017-06-09 12:06:12-04:00 Xbllfr
239270 2017-06-09 11:27:33-04:00 TbttppfdTrbdfrFrz
239271 2017-06-09 11:21:46-04:00 ND`jn`BjhD
239272 2017-06-09 11:19:34-04:00 TbnFrbnTrbdfr
239273 2017-06-09 10:55:01-04:00 bbndpntfbdfll
239274 2017-06-09 10:55:01-04:00 JTTLJTTLFBVTNJDF
................(continued for years).................
例如,使用上述数据,我们看到用户“JTTLJTTLFBVTNJDF”在过去二十四小时内至少 post 编辑了三次;那个人只为 "number of unique authors in the last twenty four hours" 贡献了 1
。
所需的输出如下所示(取决于之前 24 小时的数据):
>>> print some_function(df, past='24 hours', every='30 mins')
Index Number_of_unique_authors_in_the_last_24_hours
2017-06-09 15:00:00-04:00 12
2017-06-09 14:30:00-04:00 11
2017-06-09 14:00:00-04:00 13
...(and so forth)......
为清楚起见,这是在 15:00 说的,有 12 个 不同的 人在上次 twenty-four 中 post 编辑了消息小时,基于数据。
我尝试了 pd.Timestamp.ceil
、groupby
和 rolling
的不同组合,但没有接近我想要的。有经验的人可能知道正确的事情组合。
此外,如果有人有更好的标题想法,请告诉我。
编辑:我有点惊讶像下面这样的东西不起作用。
series = df.set_index('Message Timestamp')['Message Author']
series.resample('30 min').rolling('1D').nunique() #not supported
我知道如何让 for-loop 做我想做的事,但如果能找到 pandas-powered 做事的方式就好了。
我没能想出一些优雅的解决方案,而是通过循环遍历数据框来提出一个残酷的解决方案,希望如果您的数据集不是很大,这会起作用:
time, unique_count = [], []
for i in range(len(df)):
time.append(t)
t = df.ix[i, 'Time']
#get the datetime of 24 hours ago
yesterday = t - timedelta(days=1)
#filter the original dataframe and count unique authors
count = len(df.ix[(df['Time']<=t) &
(df['Time']>=yesterday),'Author'].unique())
unique_count.append(count)
result = pd.DataFrame({'Time': time,
'Number_of_unique_authors':unique_count})
等待有人想出更优雅的解决方案。
考虑resample
to aggregate to 30 minute intervals and then run nunique
。然后 运行 a transform
每 24 小时有条件地聚合新的唯一计数列。您需要先将时间戳设置为重新采样的索引,然后再设置为常规列以聚合到 24 小时。
import datetime
import pandas as pd
...
df = df[['Message Timestamp', 'Message Author']]
df['24-HourCount'] = df.transform(lambda x:\
len(df[(df['Message Timestamp'].between(x['Message Timestamp'] - datetime.timedelta(days=1),
x['Message Timestamp']))]['Message Author'].unique()), axis=1)
df = df.set_index('Message Timestamp')
df = df[['24-HourCount']].resample('30T').max()
print(df)
# 24-HourCount
# Message Timestamp
# 2017-06-09 14:30:00 2.0
# 2017-06-09 15:00:00 5.0
# 2017-06-09 15:30:00 NaN
# 2017-06-09 16:00:00 7.0
# 2017-06-09 16:30:00 7.0
# 2017-06-09 17:00:00 10.0
# 2017-06-09 17:30:00 11.0
# 2017-06-09 18:00:00 12.0
# 2017-06-09 18:30:00 12.0