具有公差参数的熊猫merge_asof失败

时间:2019-10-25 20:20:26

标签: python pandas

我尝试使用merge_asof函数加入2个数据框。第一个数据框包含一行失败的组件。

>>> import pandas as pd
>>> from datetime import datetime

>>> failed_date_str = '2019-05-09'
>>> failed_date = datetime.strptime(failed_date_str, '%Y-%m-%d')
>>> failed = pd.DataFrame([{"component": "a1", "failed_date": failed_date}])
>>> failed
  component failed_date
0        a1  2019-05-09

第二个数据框包含针对该组件的故障单/原因列表。

>>> future_failed_date = failed_date + pd.Timedelta(weeks=1)
>>> cases = pd.DataFrame(
...     [
...         {
..               "component": "a1",
...              "tickets": 'r'+str(o),
...              "created_date": future_failed_date - pd.Timedelta(days=o)
...         }
...         for o in range(0, 10) if o!=7
...     ]
... ).sort_values(by="created_date")
>>> cases
  component created_date tickets
8        a1   2019-05-07      r9
7        a1   2019-05-08      r8
6        a1   2019-05-10      r6
5        a1   2019-05-11      r5
4        a1   2019-05-12      r4
3        a1   2019-05-13      r3
2        a1   2019-05-14      r2
1        a1   2019-05-15      r1
0        a1   2019-05-16      r0

请注意,组件a1在2015-05-09发生了故障,并且在fail_date前后创建了多个票证。

我想在失效日期的2天内获得最接近的+/-票。我尝试以下方法:

>>> pd.merge_asof(
...     failed,
...     cases,
...     by="component",
...     left_on="failed_date",
...     right_on="created_date",
...     direction="nearest",
...     tolerance=pd.Timedelta(days=2)
... )
  component failed_date created_date tickets
0        a1  2019-05-09   2019-05-08      r8

因为我已将方向指定为最接近且公差为2天,所以我希望能得到4行对应于日期(2019-05-07至2019-05-11),但我只会得到1行如上图所示。看起来我不明白merge_asof中direction / tolerance参数的用法。 有人可以解释我在做什么错吗?

如果有帮助,我的pandas和python版本如下:

>>> pd.__version__
'0.24.2'
>>> import sys
>>> sys.version_info
sys.version_info(major=3, minor=7, micro=3, releaselevel='final', serial=0)

2 个答案:

答案 0 :(得分:2)

您的df顺序对于 for (var bla in jData) async { LatLng _markerPos = LatLng( double.parse(bla['lat']), double.parse(bla['lng']) ); String _iconImage = 'assets/images/' + bla['q'].toString() + '.png'; final bitmapIcon = await BitmapDescriptor.fromAsset(_iconImage); markers.add(Marker( position: _markerPos, markerId: MarkerId(bla['hash']), icon: bitmapIcon )); } 很重要,它将在default上进行左合并:

  

这类似于左联接,除了我们匹配最近的键   而不是等号

merge_asof

答案 1 :(得分:1)

@WenYoBen有正确答案。 "Order matters"

这是另一种方式。

您可以尝试在“组件”上进行类似这种合并的操作,然后进行过滤:

failed.merge(cases, on='component').loc[lambda x: (x['created_date'] - x['failed_date']).dt.days.abs() <= 2]

输出:

  component failed_date tickets created_date
0        a1  2019-05-09      r9   2019-05-07
1        a1  2019-05-09      r8   2019-05-08
2        a1  2019-05-09      r6   2019-05-10
3        a1  2019-05-09      r5   2019-05-11