Python 3.x 如何在datetime上使用分组条件有效地将大型数据帧拆分为两个集

Python 3.x 如何在datetime上使用分组条件有效地将大型数据帧拆分为两个集,python-3.x,pandas,performance,numpy,pandas-groupby,Python 3.x,Pandas,Performance,Numpy,Pandas Groupby,我有一个大约4000万行的大数据帧,我想把它分成两部分。列“group”表示样本所属的组,列“date”表示样本发生的日期。在下面的测试用例中,可以有多个相等的样本,但在原始集合中,情况并非如此。此外,在原始数据中,有三列。 现在,如果一组的最新日期大于或等于“2017-01-30”,我想将整个组置于s1,否则置于s2 下面的代码执行了它应该执行的操作,但速度非常慢。你有没有办法,我怎样才能加快这个过程?你知道,为什么这个方法这么慢吗? 行df['split']=grouped['date']。

我有一个大约4000万行的大数据帧,我想把它分成两部分。列“group”表示样本所属的组,列“date”表示样本发生的日期。在下面的测试用例中,可以有多个相等的样本,但在原始集合中,情况并非如此。此外,在原始数据中,有三列。 现在,如果一组的最新日期大于或等于“2017-01-30”,我想将整个组置于s1,否则置于s2

下面的代码执行了它应该执行的操作,但速度非常慢。你有没有办法,我怎样才能加快这个过程?你知道,为什么这个方法这么慢吗? 行df['split']=grouped['date']。transformlambda x:x.max
from random import randint
import numpy as np
import time
import pandas as pd

length = int(1e5)

bimonthly_days = np.arange(0, 30)
base_date = np.datetime64('2017-01-01')
random_date = base_date + np.random.choice(bimonthly_days)

groups = np.random.randint(1, int(2e4), length)
dates = np.array([base_date + np.random.choice(bimonthly_days) for _ in range(length)], dtype='datetime64[ns]')

df = pd.DataFrame({'group': groups, 'date': dates})

grouped = df.groupby('group')
date_ = np.datetime64('2017-01-30')

start_time = time.process_time()
df['split'] = grouped['date'].transform(lambda x: x.max() < date_)
dif = time.process_time() - start_time
print(f" elapsed time: {dif}")

s1 = df[df['split'] == 1].drop(columns=['split'])
s2 = df[df['split'] == 0].drop(columns=['split'])
更快的方法是创建一个系列,然后只比较一次,就像分别比较每组一样。此外,您还可以创建新的掩码,而不是用于比较的列,对于反转掩码,请使用~:

性能:

更快的方法是创建一个系列,然后只比较一次,就像分别比较每组一样。此外,您还可以创建新的掩码,而不是用于比较的列,对于反转掩码,请使用~:

性能:

试试这个:

start_time = time.process_time() df.loc[:,'split'] = df.groupby('group').date.transform('max') dif = time.process_time() - start_time print(f" elapsed time: {dif}")

s1 = df[df.split < date_] s2 = df[df.split >= date_]

 elapsed time: 0.01961299999999966
试试这个:

start_time = time.process_time() df.loc[:,'split'] = df.groupby('group').date.transform('max') dif = time.process_time() - start_time print(f" elapsed time: {dif}")

s1 = df[df.split < date_] s2 = df[df.split >= date_]

 elapsed time: 0.01961299999999966

和我的答案一样,和我的答案一样。
np.random.seed(10)
length = int(1e5)

bimonthly_days = np.arange(0, 30)
base_date = np.datetime64('2017-01-01')
random_date = base_date + np.random.choice(bimonthly_days)

groups = np.random.randint(1, int(2e4), length)
dates = np.array([base_date + np.random.choice(bimonthly_days) for _ in range(length)], dtype='datetime64[ns]')

df = pd.DataFrame({'group': groups, 'date': dates})


In [219]: %timeit df.groupby('group')['date'].transform('max') < np.datetime64('2017-01-30')
9.81 ms ± 645 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [220]: %timeit df.groupby('group')['date'].transform(lambda x: x.max() < np.datetime64('2017-01-30'))
9.05 s ± 159 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
start_time = time.process_time() df.loc[:,'split'] = df.groupby('group').date.transform('max') dif = time.process_time() - start_time print(f" elapsed time: {dif}")

s1 = df[df.split < date_] s2 = df[df.split >= date_]

 elapsed time: 0.01961299999999966
elapsed time: 6.9499130000000005