给定两个dataframe df_1
和df_2
,如何连接它们,使得datetime列df_1
位于dataframe df_2
中的start
和end
之间:
print df_1
timestamp A B
0 2016-05-14 10:54:33 0.020228 0.026572
1 2016-05-14 10:54:34 0.057780 0.175499
2 2016-05-14 10:54:35 0.098808 0.620986
3 2016-05-14 10:54:36 0.158789 1.014819
4 2016-05-14 10:54:39 0.038129 2.384590
print df_2
start end event
0 2016-05-14 10:54:31 2016-05-14 10:54:33 E1
1 2016-05-14 10:54:34 2016-05-14 10:54:37 E2
2 2016-05-14 10:54:38 2016-05-14 10:54:42 E3
得到对应的event
,其中df1.timestamp
在df_2.start
和df2.end
之间
timestamp A B event
0 2016-05-14 10:54:33 0.020228 0.026572 E1
1 2016-05-14 10:54:34 0.057780 0.175499 E2
2 2016-05-14 10:54:35 0.098808 0.620986 E2
3 2016-05-14 10:54:36 0.158789 1.014819 E2
4 2016-05-14 10:54:39 0.038129 2.384590 E3
9条答案
按热度按时间wb1gzix01#
一个简单的解决方案是从
start and end
设置closed = both
创建interval index
,然后使用get_loc
获取事件,即(希望所有日期时间都在时间戳dtype中)输出:
vc6uscn92#
首先使用IntervalIndex基于感兴趣的区间创建引用索引,然后使用get_indexer对包含感兴趣的离散事件的 Dataframe 进行切片。
参考:A question on
IntervalIndex.get_indexer.
nnvyjq4y3#
可以使用模块pandasql
lf3rwulv4#
备选方案1
备选方案2
sgtfey8w5#
在此方法中,我们假设使用了TimeStamp对象。
get_event
说明对于
df1
中的每个时间戳,例如t0 = 2016-05-14 10:54:33
,(t0 >= df2.start) & (t0 <= df2.end)
将包含1个true。(参见实施例1)。然后,与np.arange(event_num)
进行点积,以获得t0
所属事件的索引。示例:
以
t2 = 2016-05-14 10:54:35
为例最后,我们使用
transform
将每个时间戳转换为一个事件。v1l68za46#
通过将
df_1
的索引设置为timestamp字段,可以使pandas
索引对齐为您所用。只需将
df_1["event"]
设置为df_2["event"]
瞧
ugmeyewa7#
一个选项是使用pyjanitor的conditional_join:
您可以使用
how
参数决定连接类型=>left
、right
或inner
。w51jfk4q8#
在解决方案by firelynx here on StackOverflow中,这表明多态性不起作用。我不得不同意FireLynx(经过广泛的测试)。然而,将多态性的思想与the numpy broadcasting solution of piRSquared结合起来,它可以工作!
唯一的问题是,最终,在引擎盖下,numpy广播实际上做了某种交叉连接,我们过滤了所有相等的元素,给出了
O(n1*n2)
内存和O(n1*n2)
性能。也许,有人可以使这在一般意义上更有效。我在这里发帖的原因是,firelynx的解决方案问题是作为这个问题的重复而关闭的,我倾向于不同意。因为当你有多个点属于多个区间时,这个问题和其中的答案并没有给予解决方案,而只是针对属于多个区间的一个点。我下面提出的解决方案,* 确实 * 照顾到了这些n-m关系。
基本上,为多态性创建以下两个类
PointInTime
和Timespan
。顺便说一句,如果你不想使用==,而是使用其他运算符(比如!=,<,>,<=,>=),您可以为它们创建相应的函数(
__ne__
,__lt__
,__gt__
,__le__
,__ge__
)。您可以将其与广播结合使用的方式如下所示。
这给出了预期的输出。
与基本的Python类型相比,拥有类的开销可能会带来额外的性能损失,但我还没有对此进行研究。
以上就是我们如何创建“内部”连接。创建“(外部)左”、“(外部)右”和“(完全)外部”连接应该很简单。
bgibtngc9#
如果
df_2
中的时间跨度不重叠,您可以使用numpy广播将时间戳与所有时间跨度进行比较,并确定它福尔斯哪个时间跨度之间。然后使用argmax
来计算要分配哪个'Event'
(因为最多只能有1个不重叠的时间跨度)。where
条件用于NaN
任何可能落在所有时间跨度之外的对象(因为argmax
不会正确处理此问题)