使用pandas快速生成部分DataFrame

6
我有一个像这样的CSV文件。该文件大约有200万行。
2020/03/05 14:59:12.093,92.7884,93.8238
2020/03/05 14:59:14.571,97.1114,51.3926
2020/03/05 14:59:16.035,56.1351,62.6697
2020/03/05 14:59:16.992,90.3412,64.8728
         :

我希望创建Pandas数据框,以便每个数据框都有2分钟的时间跨度,并且滑动20秒如下。

DataFrame1:

2020/03/05 14:59:12.093,92.7884,93.8238
2020/03/05 14:59:14.571,97.1114,51.3926
2020/03/05 14:59:16.035,56.1351,62.6697
           :
2020/03/05 15:01:11.652,90.6966,37.9923
2020/03/05 15:01:11.918,35.8304,1.04157

数据框2:

2020/03/05 14:59:33.086,85.2834,57.327
2020/03/05 14:59:34.373,94.0521,33.8809
2020/03/05 14:59:38.752,36.8084,37.9878
           :
2020/03/05 15:01:33.090,70.4679,54.3437

等等。

我知道我可以使用以下代码来完成这个任务。

df = pd.read_csv(file_name, header=None, names=['time', 'colA', 'colB'])
df['time'] = pd.to_datetime(df['time'], format=r'%Y/%m/%d %H:%M:%S.%f')
df = df.set_index('time')
extracted_dfs = []
startdatetime = df.index[0]
enddatetime = df.index[len(df)-1]
curdatetime = startdatetime
while curdatetime < enddatetime:
    extracted_df = df[curdatetime:curdatetime + pd.Timedelta(seconds=120)].copy()
    extracted_dfs.append(extracted_df)
    curdatetime = curdatetime + pd.Timedelta(seconds=20)

但是这段代码运行速度很慢,需要大约30秒钟的时间。 我该如何加快它的执行速度?


我发现了一些有趣的东西,不确定其有效性,但值得一看。pandas.DataFrame.between_time - tidakdiinginkan
你需要所有数据的真实副本,还是视图就足够了?每20秒钟复制一次每个120秒窗口意味着你正在创建每行的6个副本,这当然会浪费资源并且速度很慢。这是出于其他原因必要的吗,比如你将以不同的方式修改每个DataFrame中的同一行? - John Zwinck
@JohnZwinck 是的,我需要真实的副本。我将修改每一行的值为第一行的差异。 - N.F.
几个问题:(1)您是否考虑过并行化,例如使用Dask? (2)回到复制与视图的问题,创建一个包含这些行副本的单个较大数据框怎么样?那样足够吗? - Roy2012
你尝试过Dask吗? - Serg
1个回答

0
我在我的2.67GHz笔记本电脑上将其降至不到6秒。 在24小时内使用了2M行数据,并提取了4,320个数据框,我猜这已经是一个足够好的缩放测试了。
似乎我们通过将curdatetime + pd.Timedelta()移出循环节省了大量时间。
### toy dataframe
start = pd.to_datetime('2020-03-05 14:00')
n = int(2e6)
df = pd.DataFrame(
    {'A': np.random.choice(100, n), 'B': np.random.choice(100, n)},
    index=start + pd.to_timedelta(np.random.rand(n)*86400, unit='seconds')
    ).sort_index()

t0 = time()

### build all start datetimes for windows
gtimes = np.arange(start=df.index[0], stop=df.index[-1],
    step=pd.Timedelta(20, unit='seconds'))
extracted_dfs = [df.loc[gt:lt] for gt, lt in
    zip(gtimes, gtimes + pd.Timedelta(120, unit='seconds'))]


print(f'runtime: {time() - t0}s')
print(*extracted_dfs[:2], sep='\n\n')

输出

runtime: 5.9694719314575195s
                                A   B
2020-03-05 14:00:00.029956126  38  47
2020-03-05 14:00:00.043794997  19  93
2020-03-05 14:00:00.274295160  24  26
2020-03-05 14:00:00.345806566   7  96
2020-03-05 14:00:00.358988998  83  18
...                            ..  ..
2020-03-05 14:01:59.811072868  45  75
2020-03-05 14:01:59.895038311  36  26
2020-03-05 14:01:59.936082342  78   6
2020-03-05 14:01:59.974735739  17  25
2020-03-05 14:01:59.985301083   1  34

[2802 rows x 2 columns]

                                A   B
2020-03-05 14:00:20.037424719  95  49
2020-03-05 14:00:20.071532168  70  37
2020-03-05 14:00:20.086438199  46  45
2020-03-05 14:00:20.197759064  60  61
2020-03-05 14:00:20.261713915  31  20
...                            ..  ..
2020-03-05 14:02:19.633312110  30  34
2020-03-05 14:02:19.646400725  50   2
2020-03-05 14:02:19.804335407  40  75
2020-03-05 14:02:19.841056690  18  75
2020-03-05 14:02:19.857622011  90  46

[2768 rows x 2 columns]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接