如何将“不匹配”的时间序列与 Pandas 合并?
在本文中,我们将了解如何将“不匹配”时间序列与 Pandas 合并。
时间序列是按固定时间间隔记录的一系列观察结果。时间序列分析有助于了解给定资产、证券或经济变量如何随时间变化
通常,数据由最有可能在天气测量或财务测量中的值的微小差异组成,当组合这些时间序列数据帧时,合并时会出现问题。 pandas 提供了这个惊人的merge_asof方法来解决它。这有助于合并不匹配的时间序列数据
将“不匹配”时间序列与 Pandas 合并
假设我们有两个时间序列数据帧 df(left) 和 df1(right)。当我们合并这两个数据帧时,如果左侧数据帧值中不存在右侧数据帧值,那么这是一个问题。所以在这种情况下,我们使用 pandas 中包含的 merge_asof。它检查右数据帧 df1 中最近的先前值并将其替换为该值
Syntax: pandas.merge_asof(left, right, on=None, left_on=None, right_on=None, left_index=False, right_index=False, by=None, left_by=None, right_by=None, suffixes=(‘_x’, ‘_y’), tolerance=None, allow_exact_matches=True, direction=’backward’)
Python3
# importing packages
import pandas as pd
# creating dataframe df(left)
df = pd.DataFrame()
df['time'] = pd.date_range('08/12/2021',
periods=6, freq='4S')
df['data_name'] = ["Geeks", "Geeks", "Geeks",
"Geeks", "GeeksforGeeks",
"GeeksforGeeks"]
df['values'] = [1, 2, 3, 4, 5, 6]
# creating datafrframe df1(right)
df1 = pd.DataFrame()
df1['time'] = pd.date_range('08/12/2021',
periods=6,
freq='6S')
df1['data_name'] = ["Geeks", "Geeks", "Geeks",
"Geeks", "GeeksforGeeks",
"GeeksforGeeks"]
df1['values'] = [7, 8, 9, 10, 11, 12]
# using merge_asof for merging left and right
df2 = pd.merge_asof(df, df1, on='time', by='data_name',
tolerance=pd.Timedelta('2s'))
# view data
print(df)
print(df1)
print(df2)
Python3
# importing packages
import pandas as pd
# creating dataframe
df = pd.DataFrame()
df['time'] = pd.date_range('08/12/2021',
periods=6,
freq='4S')
df['data_name'] = ["Geeks", "Geeks", "Geeks",
"Geeks", "GeeksforGeeks",
"GeeksforGeeks"]
df['values'] = [1, 2, 3, 4, 5, 6]
# creating dataframe
df1 = pd.DataFrame()
df1['time'] = pd.date_range('08/12/2021',
periods=6, freq='6S')
df1['data_name'] = ["Geeks", "Geeks", "Geeks",
"Geeks", "GeeksforGeeks",
"GeeksforGeeks"]
df1['values'] = [7, 8, 9, 10, 11, 12]
# allow_exact_matches=True for merging
df3 = pd.merge_asof(df, df1, on='time',
by='data_name',
allow_exact_matches=True)
# view data
print(df3)
# allow_exact_matches=False for merging df and df1
df4 = pd.merge_asof(df, df1, on='time',
by='data_name',
allow_exact_matches=False)
# view data
print(df4)
输出:
我们通过“data_name”列在“time”上合并这些数据帧(df 和 df1),但有些时间值不匹配。例如,在第二行中,A 中的时间比 B 中的时间晚两秒。
另一个问题是 values_y 是如何生成的?
在第一行中,时间在数据帧 df 和 df1 中都匹配,因此值相同,在第二行中,df 有 4s,而 df1 有 6s,两者都不相等,所以这个 merge_asof 在正确的数据帧 df1 中看起来就像前一个最接近的值,所以这里 0s 是最接近的,但为什么值是 NaN,因为我们提到要查看的容差时间范围是 2s 但它是 6s,所以 00:00:004 中的 value_y 是 NaN
Merge_asof 还提供了排除完全匹配的选项 (attr=allow_exact_matches)。
- 如果为真,则允许匹配相同的“开”值(即小于或等于/大于或等于)
- 如果为 False,则不匹配相同的“on”值(即,严格小于/严格大于)。
Python3
# importing packages
import pandas as pd
# creating dataframe
df = pd.DataFrame()
df['time'] = pd.date_range('08/12/2021',
periods=6,
freq='4S')
df['data_name'] = ["Geeks", "Geeks", "Geeks",
"Geeks", "GeeksforGeeks",
"GeeksforGeeks"]
df['values'] = [1, 2, 3, 4, 5, 6]
# creating dataframe
df1 = pd.DataFrame()
df1['time'] = pd.date_range('08/12/2021',
periods=6, freq='6S')
df1['data_name'] = ["Geeks", "Geeks", "Geeks",
"Geeks", "GeeksforGeeks",
"GeeksforGeeks"]
df1['values'] = [7, 8, 9, 10, 11, 12]
# allow_exact_matches=True for merging
df3 = pd.merge_asof(df, df1, on='time',
by='data_name',
allow_exact_matches=True)
# view data
print(df3)
# allow_exact_matches=False for merging df and df1
df4 = pd.merge_asof(df, df1, on='time',
by='data_name',
allow_exact_matches=False)
# view data
print(df4)
输出: