【问题标题】:Python Pandas - vectorize custom function instead of applyPython Pandas - 矢量化自定义函数而不是应用
【发布时间】:2017-03-17 21:48:14
【问题描述】:

我有一个带有城市名称和日期的熊猫数据框,如下所示:

In[34]: df.head(6)
Out[34]: 
       CITY        DATE
0    LONDON  2017-03-12
1    LONDON  2017-03-12
2     PARIS  2014-05-05
3     PARIS  2017-03-12
4    LONDON  2017-03-12
5  NEW-YORK  2017-03-12

我还有另一个 DataFrame 在给定的时间范围内将一个人与一个城市匹配(它基本上说这个人在开始日期和结束日期之间在这个城市)

In[51]: db.head()
Out[51]: 
       CITY PERSON       START         END
0     PARIS    ID4  2014-01-01  2017-03-16
1  NEW-YORK    ID5  2014-01-07  2016-12-31
2    LONDON    ID1  2014-01-01  2016-05-08
3  MONTREAL    ID1  2016-05-09  2017-03-16
4     TOKYO    ID5  2017-01-01  2017-03-16

我想在df 中添加一列,以确定给定日期在给定城市中的每一行。

我能够使用自定义函数 myfunc 来实现它,我使用 df.apply(lambda x: myfunc(x['CITY'], x['DATE']), axis=1) 将逐行应用于 df

myfunc 只是在db 中标识正确的PERSON,如下所示:

def myfunc(city, date):
    return db.loc[(db.CITY==city) & (db.START <= date) & (db.END >= date), 'PERSON'].values[0]

这很好用,但对于非常大的数据帧来说相当慢...我试图以某种方式将db 数据合并到df 中,或者至少实现我所做的向量化版本而不依赖于一行明智的实施。 有什么帮助吗?

【问题讨论】:

    标签: python pandas vectorization


    【解决方案1】:

    使用pd.merge_asof

    • df 必须按'DATE' 排序
    • db 必须按 'START' 排序,然后按 'END'
    • 我们使用by 参数只匹配'CITY'
    • query 最后确保我们只得到'END' &gt;= 'DATE'

    pd.merge_asof(
        df.sort_values('DATE'),
        db.sort_values(['START', 'END']),
        left_on='DATE', right_on='START', by='CITY'
    ).query('DATE <= END')
    
        CITY       DATE PERSON      START        END
    0  PARIS 2014-05-05    ID4 2014-01-01 2017-03-16
    3  PARIS 2017-03-12    ID4 2014-01-01 2017-03-16
    

    请注意,只有 'PARIS' 条目与您提供的数据匹配。

    【讨论】:

      猜你喜欢
      • 2021-04-06
      • 2012-05-11
      • 2017-04-06
      • 1970-01-01
      • 1970-01-01
      • 2018-05-13
      • 1970-01-01
      • 2023-03-02
      • 1970-01-01
      相关资源
      最近更新 更多