【问题标题】:Pandas merge only if condition is true熊猫仅在条件为真时合并
【发布时间】:2015-11-24 20:02:55
【问题描述】:

我有两个 DataFrame,我需要将两者合并,并且我需要添加一列来指定它是否被接受。

我有这个:

dfa[dfa.CONTROL.isin([334030860978638])]

Out[107]:
            CONTROL             A               B               DATE_HOUR
1629136     334030860978638     525562414612    52447860015000  2015-08-02 16:32:00
1629137     334030860978638     525562414612    52447860015000  2015-08-02 16:42:32
1629138     334030860978638     525562414612    52447860015000  2015-08-02 18:33:12
1629139     334030860978638     525562414612    52447860015000  2015-08-03 19:40:19


dfb[dfb.control.isin([334030860978638])]

Out[108]:
            control             a               b               date_hour
id              
299366338   334030860978638     525562414612    447860015000    2015-08-02 16:33:08
299392621   334030860978638     525562414612    447860015000    2015-08-02 16:43:40
299665465   334030860978638     525562414612    447860015000    2015-08-02 18:34:21

view = dfa.merge(dfb, left_on=['CONTROL', 'A', 'B'],
                right_on=['control', 'a', 'b'], how='outer')

我需要将 DATE_HOUR 与 date_hour 进行比较,如果记录在时间范围内(例如 3600 秒),我还需要确定是否及时存在多个记录,然后我将获取最近的记录并在新的接受的列我将设置为 True,否则为 False。

我的预期输出:

 CONTROL            A               B               DATE_HOUR           control             a               b               date_hour           accepted
 334030860978638    525562414612    52447860015000  2015-08-02 16:32:00 334030860978638     525562414612    52447860015000  2015-08-02 16:32:08 True
 334030860978638    525562414612    52447860015000  2015-08-02 16:42:32 334030860978638     525562414612    52447860015000  2015-08-02 16:43:40 True
 334030860978638    525562414612    52447860015000  2015-08-02 18:33:12 334030860978638     525562414612    52447860015000  2015-08-02 18:34:21 True
 334030860978638    525562414612    52447860015000  2015-08-03 19:40:19 NaN                 NaN             Nan             NaT                 False

我可以使用 apply 方法来完成这项任务吗?有人可以帮助我使用 pandas 以正确的方式做。

【问题讨论】:

  • 这是一个非常有趣的问题。您的dfa 已经包含来自dfb 的列的图像,仅缺少值。然后它变成了一个缺失数据的问题,你基本上想为dfa 的每一行求解最近邻。首先对CONTROLcontrol 进行分组,然后对DATE_HOURdate_hour 进行排序。接下来,您必须查找并针对您的原因调整最近邻算法。
  • 我会接受你的建议,谢谢,我真的很困惑。

标签: python pandas


【解决方案1】:

这个similar problem 帮助我解决了我的问题。

def nearest(group, match, groupname, lname, rname, name_field_diff='diff_minutes'):
    match = match[match[groupname] == group.name]
    try:
        nbrs = NearestNeighbors(1).fit(match[rname].values[:, None])
        dist, ind = nbrs.kneighbors(group[lname].values[:, None])
        group[lname] = group[lname]
        group[rname] = match[rname].values[ind.ravel()]
        time_diff = (group[rname] - group[lname]) / np.timedelta64(1, 'm')        
        group[name_field_diff] = time_diff.abs()
    except:
        pass
    return group

d1 = [{'CONTROL':334030860978638, 'A': 525562414612, 'B': 52447860015000, 'DATE_HOUR': '2015-08-02 16:32:00'},
{'CONTROL':334030860978638, 'A': 525562414612, 'B': 52447860015000, 'DATE_HOUR': '2015-08-02 16:42:32'},
{'CONTROL':334030860978638, 'A': 525562414612, 'B': 52447860015000, 'DATE_HOUR': '2015-08-02 18:33:12'},
{'CONTROL':334030860978638, 'A': 525562414612, 'B': 52447860015000, 'DATE_HOUR': '2015-08-02 19:40:19'}]

d2 = [{'control':334030860978638, 'a': 525562414612, 'b': 52447860015000, 'date_hour': '2015-08-02 16:33:08'},
{'control':334030860978638, 'a': 525562414612, 'b': 52447860015000, 'date_hour': '2015-08-02 16:43:40'},
{'control':334030860978638, 'a': 525562414612, 'b': 52447860015000, 'date_hour': '2015-08-02 18:34:21'}]

df1 = pd.DataFrame(d1)
df1.DATE_HOUR = pd.to_datetime(df1.DATE_HOUR, format='%Y-%m-%d %H:%M:%S')

df2 = pd.DataFrame(d2)
df2.date_hour = pd.to_datetime(df2.date_hour, format='%Y-%m-%d %H:%M:%S')

df1.groupby('CONTROL').apply(nearest, df2, 'control', 'DATE_HOUR', 'date_hour')

    A               B               CONTROL             DATE_HOUR               date_hour               diff_minutes
0   525562414612    52447860015000  334030860978638     2015-08-02 16:32:00     2015-08-02 16:33:08     1.133333
1   525562414612    52447860015000  334030860978638     2015-08-02 16:42:32     2015-08-02 16:43:40     1.133333
2   525562414612    52447860015000  334030860978638     2015-08-02 18:33:12     2015-08-02 18:34:21     1.150000
3   525562414612    52447860015000  334030860978638     2015-08-02 19:40:19     2015-08-02 18:34:21     65.966667

现在我使用我的间隙进行过滤以确定哪些记录不适合。

df1[df1.index.isin(view[(view.diff_minutes >= 60)].index)]

    A               B               CONTROL             DATE_HOUR
3   525562414612    52447860015000  334030860978638     2015-08-02 19:40:19

【讨论】:

    猜你喜欢
    • 2018-07-05
    • 1970-01-01
    • 2023-02-20
    • 1970-01-01
    • 1970-01-01
    • 2015-01-03
    • 1970-01-01
    • 2019-06-16
    • 2020-12-30
    相关资源
    最近更新 更多