簡體   English   中英

如何使用 Python 計算時間加權平均值?

[英]How to calculate time weighted average using Python?

所以我有一天中不規則間隔的數據。

活動時間 價值
17-5-2021 03:00 84.9
17-5-2021 11:00 84.9
17-5-2021 15:00 84.7
17-5-2021 23:00 84.7
18-5-2021 03:00 84.5
18-5-2021 11:00 84.5
18-5-2021 15:00 84.9
18-5-2021 23:00 84.9

我想在上述數據上使用 python 計算時間加權平均值,因為 37.5%(24 小時中有 9 小時)的值僅為 83.7,而如果計算正常平均值,它將占 17-5-2021 的 50%。

假設:如果我們沒有特定間隔的值,則采用最后一個可用值,例如:17-5-2021 04:00 的值為 84.9,因為這是最后一個可用值。 任何輸入都會有所幫助,因為我無法找到解決此問題的正確方法。 預期輸出:

計算請看圖片

最后結果

活動時間 加權平均
17-5-2021 84.79166
18-5-2021 84.71666

適當地解析數據后,您可以使用datetime將日期/時間轉換為,例如,

from datetime import datetime
datetime.strptime('17-5-2021 03:00','%d-%m-%Y %H:%M')

這將創建一個datetime對象datetime.datetime(2021, 5, 17, 3, 0)

然后可以在兩個后續(有效)值之間計算timedelta對象,只需將兩個datetime對象相減即可。 要獲得該值的權重,您可以使用生成的timedelta對象的.total_seconds()方法。

例如,這兩個條目17-5-2021 11:00 84.9 17-5-2021 15:00 84.7可用於計算第二個的權重為

w=(datetime.strptime(t2,'%d-%m-%Y %H:%M')-datetime.strptime(t1,'%d-%m-%Y %H:%M')).total_seconds()

當然,在哪里

t1='17-5-2021 11:00'
t2='17-5-2021 15:00'

結果是 w=14400。

假設您的數據位於元組列表中,如

b="""17-5-2021 03:00        84.9
17-5-2021 11:00     84.9
17-5-2021 15:00     84.7
17-5-2021 23:00     84.7
18-5-2021 03:00     84.5
18-5-2021 11:00     84.5
18-5-2021 15:00     84.9
18-5-2021 23:00     84.9""".split()
items=[(' '.join(b[i:i+2]),float(b[i+2])) for i in range(0,len(b),3)]

items產量

[('17-5-2021 03:00', 84.9), ('17-5-2021 11:00', 84.9), ('17-5-2021 15:00', 84.7), ('17-5-2021 23:00', 84.7), ('18-5-2021 03:00', 84.5), ('18-5-2021 11:00', 84.5), ('18-5-2021 15:00', 84.9), ('18-5-2021 23:00', 84.9)]

然后你可以總結每個人(w * val)並最終除以總持續時間,如

t1,val1=items[0]
dt1=datetime.strptime(t1,'%d-%m-%Y %H:%M')
dt0=dt1
result=0.
for item in items[1:]:
  t2,val2=item
  if val2==None: val2=val1 # if value doesn't exist, use previous
  dt2=datetime.strptime(t2,'%d-%m-%Y %H:%M')
  result+=val2*(dt2-dt1).total_seconds()
  dt1=dt2
  val1=val2

result/=(dt1-dt0).total_seconds()

如果該值不可用,我假設None 當然,如果第一個值不存在,這將不起作用。

我只想提一下,對於您提供的表,結果是84.73636363636363

我認為您可以使用 pandas diffgroupby滾動功能來實現這一點。 您可以使用以下步驟來實現此目的:

  1. 將事件時間轉換為日期時間
  2. 使用 diff 函數計算連續時間之間的時間差,並使用 total_seconds 將差值作為秒計算,然后除以 3600 以小時為單位進行轉換。
  3. 通過取值和時間差的乘積計算加權值
  4. 使用滾動函數計算加權平均值。 保持窗口長度為 2。將其除以期間內的小時數總和。 這里是12小時
  5. 使用 groupby 和 transform 計算加權值的每日平均值。 時間開始是 12AM
  6. 通過設置日期時間索引和傳遞窗口為 1D 來計算滾動日平均值。
import pandas as pd

df = pd.read_csv('test.csv')
df['Event Time'] = pd.to_datetime(df['Event Time'])
df['Time Diff'] = df['Event Time'].diff(periods=1).dt.total_seconds()/3600
df['Time Diff'] = df['Time Diff'].fillna(4) 
# You dont need to do the above step in large data. Dropping would be better for large data
df['Weighted Value'] = df['Value']*df['Time Diff']
# calculate the weighted average based on number of periods
df['Weighted Average'] = df['Weighted Value'].rolling(2).sum()/12
# calculate average for each day.day starts at 12AM
df['Daily Weighted Fixed Window'] = df.groupby(df['Event Time'].dt.date)['Weighted Value'].transform('sum')/24
# calculate the weighted average for last one day (stats from current time minus 24 hours)
df.set_index('Event Time', inplace=True)
df['Daily Weighted Rolling'] = df['Weighted Value'].rolling('1D').sum()/24 
活動時間 價值 時差 加權值 加權平均 每日加權固定窗口 每日加權滾動
2021-05-17 03:00:00 84.9 4 339.6 84.8 14.15
2021-05-17 11:00:00 84.9 8 679.2 84.9 84.8 42.45
2021-05-17 15:00:00 84.7 4 338.8 84.8333 84.8 56.5667
2021-05-17 23:00:00 84.7 8 677.6 84.7 84.8 84.8
2021-05-18 03:00:00 84.5 4 338 84.6333 84.7 84.7333
2021-05-18 11:00:00 84.5 8 676 84.5 84.7 84.6
2021-05-18 15:00:00 84.9 4 339.6 84.6333 84.7 84.6333
2021-05-18 23:00:00 84.9 8 679.2 84.9 84.7 84.7

我已經更新了答案。 如果您還需要什么,請告訴我。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM