nodes: 0, module; 1, function_definition; 2, function_name:_format_dataframe; 3, parameters; 4, type; 5, block; 6, typed_parameter; 7, default_parameter; 8, attribute; 9, expression_statement; 10, if_statement; 11, if_statement; 12, expression_statement; 13, if_statement; 14, return_statement; 15, identifier:df; 16, type; 17, identifier:nautical_units; 18, True; 19, identifier:pd; 20, identifier:DataFrame; 21, comment:"""
          This function converts types, strips spaces after callsigns and sorts
          the DataFrame by timestamp.
  
          For some reason, all data arriving from OpenSky are converted to
          units in metric system. Optionally, you may convert the units back to
          nautical miles, feet and feet/min.
  
          """; 22, boolean_operator; 23, block; 24, identifier:nautical_units; 25, block; 26, assignment; 27, comparison_operator:"last_position" in df.columns; 28, block; 29, call; 30, attribute; 31, comparison_operator:"callsign" in df.columns; 32, comparison_operator:df.callsign.dtype == object; 33, expression_statement; 34, expression_statement; 35, if_statement; 36, if_statement; 37, if_statement; 38, attribute; 39, call; 40, string:"last_position"; 41, attribute; 42, expression_statement; 43, attribute; 44, argument_list; 45, identifier:pd; 46, identifier:DataFrame; 47, string:"callsign"; 48, attribute; 49, attribute; 50, identifier:object; 51, assignment; 52, assignment; 53, comparison_operator:"geoaltitude" in df.columns; 54, block; 55, comparison_operator:"groundspeed" in df.columns; 56, block; 57, comparison_operator:"vertical_rate" in df.columns; 58, block; 59, identifier:df; 60, identifier:timestamp; 61, attribute; 62, argument_list; 63, identifier:df; 64, identifier:columns; 65, assignment; 66, identifier:df; 67, identifier:sort_values; 68, string:"timestamp"; 69, identifier:df; 70, identifier:columns; 71, attribute; 72, identifier:dtype; 73, attribute; 74, call; 75, attribute; 76, binary_operator:df.altitude / 0.3048; 77, string:"geoaltitude"; 78, attribute; 79, expression_statement; 80, string:"groundspeed"; 81, attribute; 82, expression_statement; 83, string:"vertical_rate"; 84, attribute; 85, expression_statement; 86, attribute; 87, identifier:tz_localize; 88, string:"utc"; 89, identifier:df; 90, call; 91, identifier:df; 92, identifier:callsign; 93, identifier:df; 94, identifier:callsign; 95, attribute; 96, argument_list; 97, identifier:df; 98, identifier:altitude; 99, attribute; 100, float:0.3048; 101, identifier:df; 102, identifier:columns; 103, assignment; 104, identifier:df; 105, identifier:columns; 106, assignment; 107, identifier:df; 108, identifier:columns; 109, assignment; 110, call; 111, identifier:dt; 112, attribute; 113, argument_list; 114, attribute; 115, identifier:strip; 116, identifier:df; 117, identifier:altitude; 118, attribute; 119, binary_operator:df.geoaltitude / 0.3048; 120, attribute; 121, binary_operator:df.groundspeed / 1852 * 3600; 122, attribute; 123, binary_operator:df.vertical_rate / 0.3048 * 60; 124, attribute; 125, argument_list; 126, call; 127, identifier:assign; 128, keyword_argument; 129, attribute; 130, identifier:str; 131, identifier:df; 132, identifier:geoaltitude; 133, attribute; 134, float:0.3048; 135, identifier:df; 136, identifier:groundspeed; 137, binary_operator:df.groundspeed / 1852; 138, integer:3600; 139, identifier:df; 140, identifier:vertical_rate; 141, binary_operator:df.vertical_rate / 0.3048; 142, integer:60; 143, identifier:pd; 144, identifier:to_datetime; 145, binary_operator:df.timestamp * 1e9; 146, attribute; 147, argument_list; 148, identifier:last_position; 149, call; 150, identifier:df; 151, identifier:callsign; 152, identifier:df; 153, identifier:geoaltitude; 154, attribute; 155, integer:1852; 156, attribute; 157, float:0.3048; 158, attribute; 159, float:1e9; 160, identifier:df; 161, identifier:query; 162, string:"last_position == last_position"; 163, attribute; 164, argument_list; 165, identifier:df; 166, identifier:groundspeed; 167, identifier:df; 168, identifier:vertical_rate; 169, identifier:df; 170, identifier:timestamp; 171, attribute; 172, identifier:tz_localize; 173, string:"utc"; 174, call; 175, identifier:dt; 176, attribute; 177, argument_list; 178, identifier:pd; 179, identifier:to_datetime; 180, binary_operator:df.last_position * 1e9; 181, attribute; 182, float:1e9; 183, identifier:df; 184, identifier:last_position
code: def _format_dataframe(
          df: pd.DataFrame, nautical_units=True
      ) -> pd.DataFrame:
          """
          This function converts types, strips spaces after callsigns and sorts
          the DataFrame by timestamp.
  
          For some reason, all data arriving from OpenSky are converted to
          units in metric system. Optionally, you may convert the units back to
          nautical miles, feet and feet/min.
  
          """
  
          if "callsign" in df.columns and df.callsign.dtype == object:
              df.callsign = df.callsign.str.strip()
  
          if nautical_units:
              df.altitude = df.altitude / 0.3048
              if "geoaltitude" in df.columns:
                  df.geoaltitude = df.geoaltitude / 0.3048
              if "groundspeed" in df.columns:
                  df.groundspeed = df.groundspeed / 1852 * 3600
              if "vertical_rate" in df.columns:
                  df.vertical_rate = df.vertical_rate / 0.3048 * 60
  
          df.timestamp = pd.to_datetime(df.timestamp * 1e9).dt.tz_localize("utc")
  
          if "last_position" in df.columns:
              df = df.query("last_position == last_position").assign(
                  last_position=pd.to_datetime(
                      df.last_position * 1e9
                  ).dt.tz_localize("utc")
              )
  
          return df.sort_values("timestamp")