Python - 在 Pandas 中平均重采样的最佳方法
Python - Best way to Average a Resample in Pandas
我有一个数据框。这是一个非常有限的例子。
userID scoreMetric timeStamp
123 5 2020-05-16 22:03:19
313 1 2020-05-16 22:03:20
123 4 2020-05-16 22:13:20
313 2 2020-05-16 22:13:20
123 2 2020-05-16 22:32:20
555 5 2020-05-16 22:32:20
123 2 2020-05-16 22:32:56
这是测试代码
import pandas as pd
from datetime import datetime
data = { 'userID': [123, 313, 123, 313, 123, 555, 123], 'scoreMetric': [5,1,4,2,2,5,2], 'timeStamp': ['2020-05-16 22:03:19', '2020-05-16 22:03:20', '2020-05-16 22:13:20', '2020-05-16 22:13:20', '2020-05-16 22:32:20', '2020-05-16 22:32:20', '2020-05-16 22:32:56'] }
df = pd.DataFrame( data, columns=['userID', 'scoreMetric', 'timeStamp'])
df.timeStamp = list( map( lambda x: datetime.strftime( datetime.strptime( x, '%Y-%m-%d %H:%M:%S'), '%Y-%m-%d %H:%M:%S' ), df.timeStamp ) )
df.timeStamp = pd.to_datetime( df.timeStamp )
我想要的是每个用户的平均值,除以一个时间段内的用户数。
我们以22:00:01-22:30:00为时间段。
我们这里有 2 个用户(123、313),每个用户都有两个时间戳。所以我想要
[ (5+4)/2 + (1+2)/2 ] / 2 = [ 4.5 + 1.5 ] / = 3 作为我的返回值。
现在我们 22:30:01 到 23:00:00。
我们这里又有 2 个用户 (123, 555),时间戳可变。所以我想要
[ (2+2)/2 + (5)/1 ] / 2 = [ 2 + 5 ] / 2 = 3.5
我认为应该有一种有效的方法可以通过重采样来做到这一点。
例如,当我只计算平均值时我可以做到
df.set_index('timeStamp').scoreMetric.resample('30M').mean().fillna(0)
然后给出 30 分钟内所有得分指标的平均值。
我已经尝试了一些方法,但似乎无法进行抽样,但随后首先对每个用户进行计算。
像这样一个简单的语句,没有方便的方法吗?我是否需要手动将时间序列分块,然后分段计算平均值等?
谢谢!
IIUC,使用pd.Grouper
按30分钟分组,userID
获取每个ID的平均值,另一个groupby
按时间只获取每个时间的平均值:
print (df.groupby([pd.Grouper(key="timeStamp", freq="1800s"), "userID"])
.mean()["scoreMetric"].groupby(level=0).mean())
timeStamp
2020-05-16 22:00:00 3.0
2020-05-16 22:30:00 3.5
如果我没理解错的话,您可以按照以下步骤操作:
import numpy as np
df.set_index('timeStamp',inplace=True)
在这里你可以过滤日期:
data=df[(df.index > '2020-05-16 22:00:01') & (df.index < '2020-05-16 22:30:00 ')]
然后:
data.groupby('userID')['scoreMetric'].mean().mean()
输出:
3
我有一个数据框。这是一个非常有限的例子。
userID scoreMetric timeStamp
123 5 2020-05-16 22:03:19
313 1 2020-05-16 22:03:20
123 4 2020-05-16 22:13:20
313 2 2020-05-16 22:13:20
123 2 2020-05-16 22:32:20
555 5 2020-05-16 22:32:20
123 2 2020-05-16 22:32:56
这是测试代码
import pandas as pd
from datetime import datetime
data = { 'userID': [123, 313, 123, 313, 123, 555, 123], 'scoreMetric': [5,1,4,2,2,5,2], 'timeStamp': ['2020-05-16 22:03:19', '2020-05-16 22:03:20', '2020-05-16 22:13:20', '2020-05-16 22:13:20', '2020-05-16 22:32:20', '2020-05-16 22:32:20', '2020-05-16 22:32:56'] }
df = pd.DataFrame( data, columns=['userID', 'scoreMetric', 'timeStamp'])
df.timeStamp = list( map( lambda x: datetime.strftime( datetime.strptime( x, '%Y-%m-%d %H:%M:%S'), '%Y-%m-%d %H:%M:%S' ), df.timeStamp ) )
df.timeStamp = pd.to_datetime( df.timeStamp )
我想要的是每个用户的平均值,除以一个时间段内的用户数。
我们以22:00:01-22:30:00为时间段。
我们这里有 2 个用户(123、313),每个用户都有两个时间戳。所以我想要 [ (5+4)/2 + (1+2)/2 ] / 2 = [ 4.5 + 1.5 ] / = 3 作为我的返回值。
现在我们 22:30:01 到 23:00:00。 我们这里又有 2 个用户 (123, 555),时间戳可变。所以我想要 [ (2+2)/2 + (5)/1 ] / 2 = [ 2 + 5 ] / 2 = 3.5
我认为应该有一种有效的方法可以通过重采样来做到这一点。
例如,当我只计算平均值时我可以做到
df.set_index('timeStamp').scoreMetric.resample('30M').mean().fillna(0)
然后给出 30 分钟内所有得分指标的平均值。
我已经尝试了一些方法,但似乎无法进行抽样,但随后首先对每个用户进行计算。
像这样一个简单的语句,没有方便的方法吗?我是否需要手动将时间序列分块,然后分段计算平均值等?
谢谢!
IIUC,使用pd.Grouper
按30分钟分组,userID
获取每个ID的平均值,另一个groupby
按时间只获取每个时间的平均值:
print (df.groupby([pd.Grouper(key="timeStamp", freq="1800s"), "userID"])
.mean()["scoreMetric"].groupby(level=0).mean())
timeStamp
2020-05-16 22:00:00 3.0
2020-05-16 22:30:00 3.5
如果我没理解错的话,您可以按照以下步骤操作:
import numpy as np
df.set_index('timeStamp',inplace=True)
在这里你可以过滤日期:
data=df[(df.index > '2020-05-16 22:00:01') & (df.index < '2020-05-16 22:30:00 ')]
然后:
data.groupby('userID')['scoreMetric'].mean().mean()
输出:
3