首页 > 解决方案 > 提高使用掩码的 iterrows() 查询的速度

问题描述

我有一个大型数据集,在内容方面看起来与此类似:

test = pd.DataFrame({'date':['2018-08-01','2018-08-01','2018-08-02','2018-08-03','2019-09-01','2019-09-02','2019-09-03','2020-01-02','2020-01-03','2020-01-04','2020-10-04','2020-10-05'],
                 'account':['a','a','a','a','b','b','b','c','c','c','d','e']})

对于每个帐户,我正在尝试创建一个列,为具有最早日期的行指定“是”(即使该最早日期重复),否则为“否”。我正在使用以下代码,该代码在该数据的较小子集上运行良好,但不适用于我的整个(较大)数据集。

first_date = test.groupby('account').agg({'date':np.min})

test['first_date'] = 'No'
for row in first_date.iterrows():
    account = row[0]
    date = row[1].date
    mask = (test.account == account) & (test.date == date)
    test.loc[mask, 'first_date'] = 'Yes'

有什么改进的想法吗?我对 python 还很陌生,并且已经遇到了使用 pandas DataFrame 的大型数据集的运行时问题。提前致谢。

标签: pythonpandas

解决方案


通常,当我们使用 pandas 或 numpy 时,我们希望避免迭代我们的数据并使用提供的矢量化方法。

用于groupby.transform获取min每一行的日期,然后用于np.where创建条件列:

m = test['date'] == test.groupby('account')['date'].transform('min')
test['first_date'] = np.where(m, 'Yes', 'No')


          date account first_date
0   2018-08-01       a        Yes
1   2018-08-01       a        Yes
2   2018-08-02       a         No
3   2018-08-03       a         No
4   2019-09-01       b        Yes
5   2019-09-02       b         No
6   2019-09-03       b         No
7   2020-01-02       c        Yes
8   2020-01-03       c         No
9   2020-01-04       c         No
10  2020-10-04       d        Yes
11  2020-10-05       e        Yes

推荐阅读