我有一个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
函数,以便0
中的每一秒1
或df
,然后每次旅行的1
s的百分比将是Harsh_Steering
中的dfTrips
。但是,某些功能无法应用于整个数据帧。例如,一个函数使速度与加速度相反,它应该按行程进行。解决这个问题的最佳方法是什么?感谢。
答案 0 :(得分:1)
我怀疑任何性能问题实际上可能是由于您的成长方式dfTrips
。我发现创建许多小的,甚至单行(或单列)数据帧然后使用pd.concat
将它们全部加入,然后尝试逐行增加一个df,速度要快几个数量级。行。
我问过类似的问题。查看接受的答案中concat
的速度有多快。
Creating large Pandas DataFrames: preallocation vs append vs concat
[编辑] 下面是为什么每次迭代都覆盖temp df并将其附加到列表中的原因(参见下面的注释):
df = pd.DataFrame(columns=np.arange(5))
df_list= []
for i in np.arange(5):
df.loc[0,:] = i
df_list.append(df)
for d in df_list:
print d
print
答案 1 :(得分:1)
我不确定它会节省时间,但你可以(通过groupby
来避免循环。首先,您将定义一个新列,例如trip_number
,以索引每个唯一的行程(这可能仍然涉及循环遍历tripNumbers)。然后按trip_number
分组。
您可以使用apply
将单个功能单独应用于每个组。
最后,您将使用水平concat
将它们连接到输出df。
请参阅' Felixble apply'文档部分。
grouped = df.groupby('trip_num')
decel_df = grouped.apply(get_deceleration_risk)
steer_df = grouped.apply(get_steering_risk)
...
dfTrips = pd.concat([decel_df, steer_df, ...], axis=1)
dfTrips.columns = ['Harsh_Deceleration', 'Harsh_Steering', ...]