微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何映射两个不同的时间序列,并在映射时执行计算?

如何解决如何映射两个不同的时间序列,并在映射时执行计算?

我有两个带有时间序列数据的CSV。一张桌子是连续的,从01.01.2017 00:00开始。从那里开始,每一行代表一个小时(1.表)。数据看起来像这样:

  1. 表aka df1:
Date,Volume
2017-02-03 12-PM,9787.51
2017-02-03 01-PM,9792.01
2017-02-03 02-PM,9803.94
2017-02-03 03-PM,9573.99

一个表包含发生的事件,并由UNIX日期时间以秒为单位进行了序列化。我可以使用以下代码将其转换为日期时间并按小时进行分组:

df['datetime'] = pd.to_datetime(df['created_utc'],unit='s')
df['datetime'] = pd.to_datetime(df['datetime'],format="%Y-%m-%d %I-%p")
df['date_by_hour'] = df['datetime'].apply(lambda x: x.strftime('%Y-%m-%d %H:00'))

这产生了以下数据:

  1. 表aka df2:
created_utc,score,compound,datetime,date_by_hour
1486120391,156,0.125,2017-02-03 12:13:11,2017-02-03 12:00:00
1486125540,1863,0.475,2017-02-03 13:39:00,2017-02-03 13:00:00
1486126013,863,0.889,2017-02-03 13:46:53,2017-02-03 13:00:00
1486130203,23,0.295,2017-02-03 14:56:43,2017-02-03 14:00:00

现在,我需要将事件(2.table)映射到1. Table的时间序列。如果在一小时内发生了多个事件,我需要加分并计算化合物的平均数。最后,我想要一个这样的数据框:

  1. 最终数据框
Date,Volume,2017-02-03 12-PM,9787.51,2017-02-03 01-PM,9792.01,2726,0.682,2017-02-03 02-PM,9803.94,2017-02-03 03-PM,9573.99,

我知道下面的代码行不通并且是错误的,但是我想表明我在想如何实现此目标。我以为可以遍历事件表df2的每一行,并比较日期时间是否匹配。如果是这样,我将计算分数和复合值。问题是我知道一个人不应该循环访问一个数据框,也不知道如何同时循环通过另一个数据框,并根据前面的行执行正确的计算...

for index,row in df2.iterrows():
    memory_score = 0
    memory_compound = 0
    if df1['Date'] == df2['date_by_hour']:
        df1['score'] = row['score'] + memory_score
        df1['compound'] = (row['compound'] + memory_compound) / 2    

如何获得最终数据框?我必须使用一些熊猫魔术来完成这项工作,并将时间序列数据映射到正确的时间。

预先感谢和问候

编辑:在一小时内事件可能是不确定的事件数。在这个简单的示例中,我只是选择了2,但在某些情况下可能是5000左右或0。

解决方法

# import necessary packages,set seed

import pandas as pd
import datetime
import random
random.seed(42)

设置

让我们使用this创建一个示例df1

numdays=5
base = datetime.datetime(2017,2,3,12)
date_list = [base + datetime.timedelta(hours=x) for x in range(numdays)]

然后,using

df1 = pd.DataFrame.from_dict({'Date': date_list,'Volume': [random.randint(9000,11000) for _ in range(len(date_list))]})

这给我们:

+----+---------------------+----------+
|    | Date                |   Volume |
|----+---------------------+----------|
|  0 | 2017-02-03 12:00:00 |     9228 |
|  1 | 2017-02-03 13:00:00 |     9051 |
|  2 | 2017-02-03 14:00:00 |    10518 |
|  3 | 2017-02-03 15:00:00 |     9563 |
|  4 | 2017-02-03 16:00:00 |     9501 |
+----+---------------------+----------+

我们也创建df2

random_date_list = [base + datetime.timedelta(hours=x*random.uniform(0,2)) for x in range(7)]

df2 = pd.DataFrame({'datetime':random_date_list,'score':[random.randint(20,200) for _ in range(len(random_date_list))],'compound': [random.uniform(0,1) for _ in range(len(random_date_list))]},index=[x for x in range(len(random_date_list))])

给出:

+----+----------------------------+---------+------------+
|    | datetime                   |   score |   compound |
|----+----------------------------+---------+------------|
|  0 | 2017-02-03 12:00:00        |      75 |   0.71602  |
|  1 | 2017-02-03 13:28:22.592742 |      79 |   0.701325 |
|  2 | 2017-02-03 14:42:24.472619 |     149 |   0.41952  |
|  3 | 2017-02-03 17:21:11.078662 |     174 |   0.449209 |
|  4 | 2017-02-03 12:41:43.838380 |      26 |   0.278191 |
|  5 | 2017-02-03 16:13:09.185509 |     163 |   0.8693   |
|  6 | 2017-02-03 12:21:27.239880 |      70 |   0.758807 |
+----+----------------------------+---------+------------+

实际计算

让我们在df2中创建一个带有日期时间对象以达到小时分辨率的列:

df2['Date'] = df2['datetime'].apply(lambda x: x.replace(minute=0,second=0,microsecond=0))

我们可以merge df1df2replace NaNs with 0s

merged = pd.merge(df1,df2,on='Date',how='outer')
merged.fillna(0,inplace=True)

现在计算所需的新列:

newscoredf=merged.groupby('Date')[['score']].agg('sum')
newcompounddf=merged.groupby('Date')[['compound']].agg('mean')

让我们吸引他们,并添加我们留下的Volume列:

final = pd.concat([df1.set_index('Date')[['Volume']],newscoredf,newcompounddf],axis=1)

为您提供想要的东西。

final

+---------------------+----------+---------+------------+
| Date                |   Volume |   score |   compound |
|---------------------+----------+---------+------------|
| 2017-02-03 12:00:00 |     9228 |     171 |   0.584339 |
| 2017-02-03 13:00:00 |     9051 |      79 |   0.701325 |
| 2017-02-03 14:00:00 |    10518 |     149 |   0.41952  |
| 2017-02-03 15:00:00 |     9563 |       0 | nan        |
| 2017-02-03 16:00:00 |     9501 |     163 |   0.8693   |
| 2017-02-03 17:00:00 |      nan |     174 |   0.449209 |
+---------------------+----------+---------+------------+

检查:考虑从12开始一个小时内发生的行。得分:得分:75 + 26 + 70 =171。复合:(0.71602 + 0.278191 + 0.758807)/ 3 = 0.584339。两者都与我们结果的第一行一致。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。