如何在 Python 中的一个常规 Pandas DataFrame 中加入许多零散的时间序列
Posted
技术标签:
【中文标题】如何在 Python 中的一个常规 Pandas DataFrame 中加入许多零散的时间序列【英文标题】:How to join many fragmented time series in one regular Pandas DataFrame in Python 【发布时间】:2019-12-09 18:58:24 【问题描述】:我必须处理从一些 CSV 导入的时间序列数据,这些数据可能如下所示:
import pandas as pd
csv_a = [["Sensor_1", '2019-05-25 10:00', 25, 60],
["Sensor_2", '2019-05-25 10:00', 30, 45],
["Sensor_1", '2019-05-25 10:05', 26, None],
["Sensor_2", '2019-05-25 10:05', 30, 46],
["Sensor_1", '2019-05-25 10:10', 27, 63],
["Sensor_1", '2019-05-25 10:20', 28, 62]]
df_a = pd.DataFrame(csv_a, columns=["Sensor", "Timestamp", "Temperature", "Humidity"])
df_a["Timestamp"] = (pd.to_datetime(df_a["Timestamp"]))
csv_b = [["Sensor_1", '2019-05-25 10:05', 1020],
["Sensor_2", '2019-05-25 10:05', 956],
["Sensor_3", '2019-05-25 10:05', 990],
["Sensor_1", '2019-05-25 10:10', 1021],
["Sensor_2", '2019-05-25 10:10', 957],
["Sensor_3", '2019-05-25 10:10', 992],
["Sensor_1", '2019-05-25 10:15', 1019]]
df_b = pd.DataFrame(csv_b, columns=["Sensor", "Timestamp", "Pressure"])
df_b["Timestamp"] = (pd.to_datetime(df_b["Timestamp"]))
如您所见,我们有 3 个传感器。每个传感器都有自己的时间序列,测量温度、湿度和压力。但是,数据在两个 CSV 中是零散的,并且可能有很多间隙等。
目标是将所有数据连接到一个有序且规则的数据框中,如下所示:
Timestamp Sensor Temperature Humidity Pressure
0 2019-05-25 10:00:00 Sensor_1 25.0 60.0 NaN
1 2019-05-25 10:00:00 Sensor_2 30.0 45.0 NaN
2 2019-05-25 10:00:00 Sensor_3 NaN NaN NaN
3 2019-05-25 10:05:00 Sensor_1 26.0 NaN 1020.0
4 2019-05-25 10:05:00 Sensor_2 30.0 46.0 956.0
5 2019-05-25 10:05:00 Sensor_3 NaN NaN 990.0
6 2019-05-25 10:10:00 Sensor_1 27.0 63.0 1021.0
7 2019-05-25 10:10:00 Sensor_2 NaN NaN 957.0
8 2019-05-25 10:10:00 Sensor_3 NaN NaN 992.0
9 2019-05-25 10:15:00 Sensor_1 NaN NaN 1019.0
10 2019-05-25 10:15:00 Sensor_2 NaN NaN NaN
11 2019-05-25 10:15:00 Sensor_3 NaN NaN NaN
12 2019-05-25 10:20:00 Sensor_1 28.0 62.0 NaN
13 2019-05-25 10:20:00 Sensor_2 NaN NaN NaN
14 2019-05-25 10:20:00 Sensor_3 NaN NaN NaN
这背后的逻辑是要认识到,全球范围内,CSV 中的数据从 10:00 开始,到 10:20 结束。并且我们有 3 个可能的变量用于 3 个不同的传感器。所以我希望前 2 列(时间戳和传感器)是规则的、有序的且没有间隙。其余列(温度、湿度和压力)将尽可能使用 CSV 中的数据填充。
我尝试使用 pandas 合并功能以多种不同方式执行此操作,但无法获得我想要的结果。我希望有经验的人可以帮助我。
【问题讨论】:
【参考方案1】:首先通过concat
和DataFrame.set_index
将两个DataFrame
s 连接在一起,如果可能重复,使用由时间戳和Sensor
s 创建的唯一MultiIndex
的总和。
然后用DataFrame.reindex
加上MultiIndex.from_product
的缺失行,用date_range
加上最小和最大日期:
df = (pd.concat([df_a.set_index(['Timestamp','Sensor']),
df_b.set_index(['Timestamp','Sensor'])], sort=True)
.sum(level=[0,1],min_count=1))
d = df.index.get_level_values(0)
mux = pd.MultiIndex.from_product([pd.date_range(d.min(), d.max(), freq='5Min'),
df.index.get_level_values(1).unique()], names=df.index.names)
df = df.reindex(mux).reset_index()
print (df)
Timestamp Sensor Humidity Pressure Temperature
0 2019-05-25 10:00:00 Sensor_1 60.0 NaN 25.0
1 2019-05-25 10:00:00 Sensor_2 45.0 NaN 30.0
2 2019-05-25 10:00:00 Sensor_3 NaN NaN NaN
3 2019-05-25 10:05:00 Sensor_1 NaN 1020.0 26.0
4 2019-05-25 10:05:00 Sensor_2 46.0 956.0 30.0
5 2019-05-25 10:05:00 Sensor_3 NaN 990.0 NaN
6 2019-05-25 10:10:00 Sensor_1 63.0 1021.0 27.0
7 2019-05-25 10:10:00 Sensor_2 NaN 957.0 NaN
8 2019-05-25 10:10:00 Sensor_3 NaN 992.0 NaN
9 2019-05-25 10:15:00 Sensor_1 NaN 1019.0 NaN
10 2019-05-25 10:15:00 Sensor_2 NaN NaN NaN
11 2019-05-25 10:15:00 Sensor_3 NaN NaN NaN
12 2019-05-25 10:20:00 Sensor_1 62.0 NaN 28.0
13 2019-05-25 10:20:00 Sensor_2 NaN NaN NaN
14 2019-05-25 10:20:00 Sensor_3 NaN NaN NaN
【讨论】:
好的,所以我看到成功的关键是首先将所有数据粘合在一起,然后使用公共字段(时间戳和传感器)作为索引对最终输出进行分组、排序和格式化。非常有用的方法,谢谢。【参考方案2】:您可以使用pandas
库的merge
函数。它提供了在两列上连接两个数据框的选项。可以参考this
试试下面的代码:
df = pd.merge(df_a, df_b, how='outer', on=['Timestamp','Sensor'])
【讨论】:
【参考方案3】:怎么样:
df_a['Timestamp'] = df_a['Timestamp'].astype(str)
df_b['Timestamp']= df_b['Timestamp'].astype(str)
df = pd.merge(df_a, df_b, how='outer', on='Timestamp').sort_values(by=('Timestamp','Sensor'))
df['Timestapm'] = pd.to_datetime(df['Timestamp'])
如果您的数据框 df_b 具有sensor_3
everywhere,则合并功能应该为您提供所需的合并输出。外部连接将为您提供一切。
这是合并选项:
sort_values 用于排序。
【讨论】:
【参考方案4】:你可以看看之前的帖子如何 Merge Two CSV files in Python。
也许最好先合并这两个文件,然后根据您的要求对它们进行排序。你可以在这里找到教程https://pandas.pydata.org/pandas-docs/version/0.19/generated/pandas.DataFrame.sort.html
【讨论】:
以上是关于如何在 Python 中的一个常规 Pandas DataFrame 中加入许多零散的时间序列的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Pandas 在 Python 中基于同一行中的另一个单元格设置单元格值