【发布时间】:2016-09-24 18:30:19
【问题描述】:
我有一个pandas 数据框df,其中包含每个驱动程序的秒到秒数据(经度、纬度等)。数据框由多个行程组成。有一个名为Event_Type 的功能可用于确定行程的开始和结束:
ignitionOnList = df[df['Event_Type'] == 'Ignition On'].index.tolist()
ignitionOffList = df[df['Event_Type'] == 'Ignition Off'].index.tolist()
所以,假设我在这个数据框中有 5 次行程。 ignitionOnList 和 ignitionOffList 的长度为 5。我想专门对每次旅行进行分析并将它们存储在 pandas 数据框中。这是我的工作:
dfTrips = pd.DataFrame({'Date' : [],'Vehicle' : [], 'Trip_Number' : [], 'Start_Time' : [], 'Duration' : [],
'Collision': [],'Harsh_Steering' : [], 'Harsh_Deceleration' : [], 'Harsh_Acceleration' : [],
'Harsh_Preferred_Speed' : []})
tripCount = -1
tripNumbers = len(ignitionOnList)
for tripNumber in range(tripNumbers):
tripCount += 1
dfTemp = df.loc[ignitionOnList[tripNumber]:ignitionOffList[tripNumber]+1]
# Doing stuff to this temporary data frame and storing them, for example:
dfTrips.loc[tripCount,'Start_Time'] = dfTemp.loc[0,'Time'].strftime("%H:%M:%S")
dfTrips.loc[tripCount,'Finish_Time'] = dfTemp.loc[dfTemp.shape[0]-1,'Time'].strftime("%H:%M:%S")
# Using a function I have defined named `get_steering_risk` to get risky behaviour for each trip
dfTrips.loc[tripCount,'Harsh_Deceleration'] = get_deceleration_risk(dfTemp)
dfTrips.loc[tripCount,'Harsh_Steering'] = get_steering_risk(dfTemp)
这行得通。但我猜在没有 for 循环的情况下,在 Python 中有更好的方法可以做到这一点。我不确定我是否可以简单地使用apply,因为我没有将相同的函数应用于整个数据框。
另一种方法可能是重新定义函数,以便它们在df 中生成一列
并将它们应用于整个数据框,然后汇总每次行程的结果。例如,get_steering_risk 函数可以定义为在df 中每秒生成0 或1,然后每次行程的1s 的百分比将是Harsh_Steering 在dfTrips 中。但是,某些功能不能应用于整个数据框。例如,一个函数对速度与加速度进行回归,它应该逐个行程地完成。解决这个问题的最佳方法是什么?谢谢。
【问题讨论】:
-
你的秒到秒数据框很大吗?我经常发现打开一次大 df 然后对小的临时 df 进行所有分析会更节省内存,就像在您的示例中一样。
-
另外,循环的读取端看起来效率并不低。进入 dfTemp 的每个行块只读取一次。
-
@andrew
df数据框一点也不大。它来自一个 2 Mb 的 csv 文件。但是,我有数千个这样的文件需要输入到我的代码中,这就是为什么我尽可能让代码更有效率。 -
根据我在下面的回答,我认为您会看到由于逐行构建
dfTrips而对性能造成的影响要大得多,然后您将从循环中看到。 Pandasread_csv解析器也非常快。我不会担心 I/O 开销。