利用Pandas数据过滤减少运算时间

2024-06-12 09:43:57 浏览数 (2)

当处理大型数据集时,使用 Pandas 可以提高数据处理的效率。Pandas 提供了强大的数据结构和功能,包括数据过滤、筛选、分组和聚合等,可以帮助大家快速减少运算时间。

1、问题背景

我有一个包含37456153行和3列的Pandas数据帧,其中列包括Timestamp、Span和Elevation。每个时间戳值都有大约62000行Span和Elevation数据,如下所示(以时间戳=17210为例):

代码语言:javascript复制
    Timestamp       Span  Elevation

94614 17210 -0.019766 36.571 94615 17210 -0.019656 36.453 94616 17210 -0.019447 36.506 94617 17210 -0.018810 36.507 94618 17210 -0.017883 36.502

... ... ... ... 157188 17210 91.004000 33.493 157189 17210 91.005000 33.501 157190 17210 91.010000 33.497 157191 17210 91.012000 33.500 157192 17210 91.013000 33.503

如上所示,Span数据不是等间隔的,而我需要它成为等间隔的。因此,我想出了一个将它转换为等间隔格式的代码。我知道要分析的起始和结束位置。然后,我定义了一个名为delta的参数作为增量。我创建了一个名为mesh的numpy数组,它保存了我最终想要得到的等间隔Span数据。最后,我决定对数据帧进行迭代,以获取给定的时间戳(代码中为17300),来测试它的运行速度。代码中for循环计算了在每个增量处 /-0.5delta范围内的平均Elevation值。

我的问题是: 过滤数据帧并计算单个迭代的平均Elevation需要603毫秒。对于给定的参数,我必须进行9101次迭代,这导致此循环需要大约1.5小时的计算时间。而且,这只是对于单个时间戳值,我还有600个时间戳值(全部需要900个小时才能完成吗?)。是否有办法可以加快此循环的速度?感谢任何意见!

2、解决方案

方法一:使用np.searchsorted矢量化整个操作

代码语言:javascript复制
import numpy as np
import pandas as pd
​
# MESH GENERATION
start = 0
end = 91
delta = 0.01
​
mesh = np.linspace(start, end, num=(end/delta   1))
midpoints = (mesh[:-1]   mesh[1:]) / 2
idx = np.searchsorted(midpoints, df.Span)
averages = np.bincount(idx, weights=df.Elevation, minlength=len(mesh))
averages /= np.bincount(idx, minlength=len(mesh))

方法二:将数据转换为dataframe,并添加一个偏移的条目,使dataframe中的每个条目都代表新的均匀Span的一个步骤。

代码语言:javascript复制
# MESH GENERATION
start = 0
end = 91
delta = 0.01
​
mesh = np.linspace(start, end, num=(end/delta   1))
mesh_df = pd.DataFrame(mesh, columns=['Equal_Span'])
mesh_df['Equal_Span_Prev'] = mesh_df['Equal_Span'].shift(1)
mesh_df = mesh_df.dropna()

方法三:将数据导入sqlite数据库,并使用SQL进行join操作。

代码语言:javascript复制
import sqlite3
import pandas as pd
​
# MESH GENERATION
start = 0
end = 91
delta = 0.01
​
mesh = np.linspace(start, end, num=(end/delta   1))
mesh_df = pd.DataFrame(mesh, columns=['Equal_Span'])
mesh_df['Equal_Span_Prev'] = mesh_df['Equal_Span'].shift(1)
mesh_df = mesh_df.dropna()
​
# Ship data to in-memory sqlite database
con = sqlite3.connect(':memory:')
df.to_sql('df', con, index=False)
mesh_df.to_sql('mesh_df', con, index=False)
​
# Join data using SQL
join_df = pd.read_sql("""SELECT a.Timestamp, a.Span, a.Elevation, b.Equal_Span
                         FROM df a, mesh_df b
                         WHERE a.Span BETWEEN b.Equal_Span_Prev AND b.Equal_Span""", con)
​
# Get mean of Elevation
join_df.groupby(['Timestamp','Equal_Span'])['Elevation'].mean()

通过以上方法可以有效地提高Pandas数据过滤的运行速度。

这些技巧可以帮助大家根据特定条件快速地筛选出需要的数据,从而减少运算时间。根据大家的具体需求和数据集的特点,选择适合的方法来进行数据过滤。

0 人点赞