如何在 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】:

首先通过concatDataFrame.set_index 将两个DataFrames 连接在一起,如果可能重复,使用由时间戳和Sensors 创建的唯一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_3everywhere,则合并功能应该为您提供所需的合并输出。外部连接将为您提供一切。 这是合并选项: 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:如何修改DataFrame中某一列的值?

如何使用 Pandas 在 Python 中基于同一行中的另一个单元格设置单元格值

Plotly:如何在绘图线图中的特定点添加标记(python / pandas)

如何在python中修改pandas中的排名

pandas python 怎么删除表格中的某一行

如何利用Python中的Pandas库绘制柱形图