我有两个数据帧。
数据帧1(df1):
1 object_name time_epoch_ms source data
2 a 1538518822490 source_1 some_data
3 b 1538528822490 source_2 some_data
4 b 1538538822490 source_2 some_data
5 b 1538548822490 source_3 some_data
6 b 1538558822490 source_1 some_data
7 c 1538568822490 source_2 some_data
8 c 1538578822490 source_2 some_data
9 c 1538588822490 source_2 some_data
... etc etc
数据帧2(df2):
1 object_name time_epoch_ms new_data
2 a 1538518722490 x
3 b 1538528822490 y
4 b 1538518922490 z
5 b 1538519922490 a
6 b 1538598822490 b
7 c 1538548822490 c
8 c 1538538822490 c
9 c 1538528822490 d
... etc etc
这两个表中的条目提供了有关在不同时间点具有object_names的对象的信息。
我想结合这两个表,以便在数据框#1中指定的特定时间使用对象名使用的源来扩充数据框#2。
问题:两个表中的时间戳不完全匹配。表2中存在一些时间戳,表1中不存在。但是,它们应大致对应于小时。表1中缺少一些时间戳,因此“最后可用数据”是最好的。
有没有办法利用熊猫的合并能力执行以下步骤?
我的方法:
我目前正在执行.apply以从df2中获取每一行,并在df1中找到该对象的所有时间戳(如果存在)。然后,我返回最接近的匹配项或null。
我想知道是否有使用pandas的merge或concat功能的更优雅的方式,但是我很难理解在这种情况下如何使用它们以及如何根据小时来处理数据填充和匹配(无需进行单独的预处理就可以在其中获得一个小时列)。
答案 0 :(得分:1)
通常,Pandas使“等值连接”变得容易,但是其他种类则比较困难。在这种情况下,您很幸运,因为有一个不错的方法叫做merge_asof
,它可以满足您的需求。
关于如何设置数据有些古怪,但是MWE是:
from io import StringIO
import pandas as pd
df1 = pd.read_table(StringIO("""1 object_name time_epoch_ms source data
2 a 1538518822490 source_1 some_data_1
3 b 1538528822490 source_2 some_data_2
4 b 1538538822490 source_2 some_data_3
5 b 1538548822490 source_3 some_data_4
6 b 1538558822490 source_1 some_data_5
7 c 1538568822490 source_2 some_data_6
8 c 1538578822490 source_2 some_data_7
9 c 1538588822490 source_2 some_data_8
"""), sep=r"\s+", index_col=0)
df2 = pd.read_table(StringIO("""1 object_name time_epoch_ms new_data
2 a 1538518722490 x
3 b 1538528822490 y
4 b 1538518922490 z
5 b 1538519922490 a
6 b 1538598822490 b
7 c 1538548822490 c
8 c 1538538822490 c
9 c 1538528822490 d
"""), sep=r"\s+", index_col=0)
pd.merge_asof(
df2.sort_values(['time_epoch_ms', 'object_name']),
df1.sort_values(['time_epoch_ms', 'object_name']),
by="object_name", on="time_epoch_ms",
direction='forward',
).sort_values(['object_name', 'time_epoch_ms'])
这回馈:
object_name time_epoch_ms new_data source data
0 a 1538518722490 x source_1 some_data_1
1 b 1538518922490 z source_2 some_data_2
2 b 1538519922490 a source_2 some_data_2
3 b 1538528822490 y source_2 some_data_2
7 b 1538598822490 b NaN NaN
4 c 1538528822490 d source_2 some_data_6
5 c 1538538822490 c source_2 some_data_6
6 c 1538548822490 c source_2 some_data_6
另请参见Pandas equivalent of SQL non-equi JOIN。还有merge_ordered
,但我认为这对您的情况没有帮助。