如何在熊猫数据框中组合从for循环输出的多个字典?

时间:2018-03-02 16:55:55

标签: python pandas dictionary

链接到上一个问题

我正在使用名为TraCI的工具,该工具允许用户使用Python控制名为SUMO的模拟软件。因此,我的代码包含traciPython模块的函数。我之前已经询问了您可能希望看到的question代码traci。但是,我想澄清这个问题是关于Python。我之前提到traci只是因为你会看到该模块的功能。

我想做什么?

我想将多个单元的输出字典组合成pandas数据框。以下是我的输入数据:

import numpy as np
import pandas as pd
from pandas import Series, DataFrame


data = {'ADO_name':['car1','car1','car1','car1','car1','car1',
                    'car2','car2','car2','car2','car2','car2'],
        'Time_sec':[0,1,2,3,4,5,
                    0,1,2,3,4,5],
        'Speed.mps':[13.9,15,18,20,21,22,
                     0,   0, 13.9,13.9,13.9,14.5]}

dframe = DataFrame(data)

dframe = dframe.sort_values('Time_sec')  

如何生成数据?

上面的输入dframe用于循环运行两辆车的给定时间步长和给定速度,如下所示:

step = 0

#running traci
while step <= 1:
    traci.simulationStep() # traci function to start a simulation step
    for ado in dframe["ADO_name"].unique():

        traci.vehicle.setSpeed(ado, dframe[(dframe.Time_sec == step) & (dframe.ADO_name == ado)]['Speed.kph']) # traci function to set the speed of both cars 
        print(traci.vehicle.getSubscriptionResults(ado)) # traci function to get results

    step += 1  

输出

{64: 0.0, 80: 'highway1.1', 81: 'highway1.1_0', 86: 400.0}
{64: 0.0, 80: 'highway1.1', 81: 'highway1.1_1', 86: 100.0}
{64: 13.9, 80: 'highway1.1', 81: 'highway1.1_0', 86: 413.9}
{64: 0.0, 80: 'highway1.1', 81: 'highway1.1_1', 86: 100.0}  

函数traci.vehicle.getSubscriptionResults()产生速度(key = 64),roadID(80),laneID(81)和lane位置(86)变量作为每个时间步和每辆车的输出。在上面的结果中,前2个字典表示时间步长0中car1car2(一个接一个)的输出。同样,最后2个表示时间步骤1中的输出。我想要将此输出组合在一个数据框中。

预期输出

  ADO_name  Speed.mps        laneID  lane_pos      roadID  step
0     car1        0.0  highway1.1_0     400.0  highway1.1     0
1     car2        0.0  highway1.1_1     100.0  highway1.1     0
2     car1       13.9  highway1.1_0     413.9  highway1.1     1
3     car2        0.0  highway1.1_0     100.0  highway1.1     1

我尝试了什么?

我是Pythonpandas的新手,所以尽管花了好几个小时来解决这个问题,但我还没有成功。我知道我可以使用字典功能,例如traci.vehicle.getSubscriptionResults(ado).get(64)获取速度变量。但我不知道如何在每个循环中追加结果。我也试过以下:

print(DataFrame(traci.vehicle.getSubscriptionResults(ado), index = [step]))
>     64          80            81     86
0  0.0  highway1.1  highway1.1_0  400.0
    64          80            81     86
0  0.0  highway1.1  highway1.1_1  100.0
     64          80            81     86
1  13.9  highway1.1  highway1.1_0  413.9
    64          80            81     86
1  0.0  highway1.1  highway1.1_1  100.0 

但这不是我的预期。请指导我如何处理这个问题?如何收集结果并清理字典以获得最终预期输出?任何相关的示例/博客都会有所帮助。谢谢。

1 个答案:

答案 0 :(得分:1)

我看到的解决方案是修改模拟循环,将每个字典附加到列表中,插入ADO_namestep的新密钥,然后将该字典列表传递给DataFrame循环之后。

这是修改后的循环。这是未经测试的,但我相信这个想法是正确的:

step = 0
# Create an empty list before the loop
list_of_dicts = []

#running traci
while step <= 1:
    traci.simulationStep() # traci function to start a simulation step
    for ado in dframe["ADO_name"].unique():

        traci.vehicle.setSpeed(ado, dframe[(dframe.Time_sec == step) & (dframe.ADO_name == ado)]['Speed.kph']) # traci function to set the speed of both cars 
        print(traci.vehicle.getSubscriptionResults(ado)) # traci function to get results

        # A block of new code
        d = traci.vehicle.getSubscriptionResults(ado)
        d['ADO_name'] = ado
        d['step'] = step
        list_of_dicts.append(d)

    step += 1  

假设循环没有错误运行,你应该得到一个像这样的列表:

ds = [{64: 0.0, 80: 'highway1.1', 81: 'highway1.1_0', 86: 400.0, 'ADO_name': 'car1', 'step': 0}, 
      {64: 0.0, 80: 'highway1.1', 81: 'highway1.1_1', 86: 100.0, 'ADO_name': 'car2', 'step': 0},
      {64: 13.9, 80: 'highway1.1', 81: 'highway1.1_0', 86: 413.9, 'ADO_name': 'car1', 'step': 1}, 
      {64: 0.0, 80: 'highway1.1', 81: 'highway1.1_1', 86: 100.0, 'ADO_name': 'car2', 'step': 1}]

达到所需输出的最后一步:

result = pd.DataFrame(ds).rename(columns={64: 'Speed.mps', 
                                          80: 'roadID', 
                                          81: 'laneID',
                                          86: 'lane_pos'})

result
   Speed.mps      roadID        laneID  lane_pos ADO_name  step
0        0.0  highway1.1  highway1.1_0     400.0     car1     0
1        0.0  highway1.1  highway1.1_1     100.0     car2     0
2       13.9  highway1.1  highway1.1_0     413.9     car1     1
3        0.0  highway1.1  highway1.1_1     100.0     car2     1