code: def compute_map(ranks, gnd, kappas):
      """
      Computes the mAP for a given set of returned results.
  
      Credits:
          https://github.com/filipradenovic/revisitop/blob/master/python/evaluate.py
  
      Usage:
        map = compute_map (ranks, gnd)
              computes mean average precsion (map) only
  
        map, aps, pr, prs = compute_map (ranks, gnd, kappas)
          -> computes mean average precision (map), average precision (aps) for
             each query
          -> computes mean precision at kappas (pr), precision at kappas (prs) for
             each query
  
       Notes:
       1) ranks starts from 0, ranks.shape = db_size X #queries
       2) The junk results (e.g., the query itself) should be declared in the gnd
          stuct array
       3) If there are no positive images for some query, that query is excluded
          from the evaluation
      """
  
      map = 0.0
      nq = ranks.shape[-1]  # number of queries
      aps = np.zeros(nq)
      pr = np.zeros(len(kappas))
      prs = np.zeros((nq, len(kappas)))
      nempty = 0
      for i in np.arange(nq):
          qgnd = np.array(gnd[i]["ok"])
  
          # Remove pos database queries that are not in the prediction.
          # this is only used in DEBUG_MODE where we limit the number of db images.
          qgnd = qgnd[qgnd < ranks.shape[0]]
  
          # no positive images, skip from the average
          if qgnd.shape[0] == 0:
              aps[i] = float("nan")
              prs[i, :] = float("nan")
              nempty += 1
              continue
              print(f"Skipping: {i}")
  
          try:
              qgndj = np.array(gnd[i]["junk"])
  
              # Remove junk database queries that are not in the prediction.
              # this is only used in DEBUG_MODE where we limit the number of db images.
              qgndj = qgndj[qgndj < ranks.shape[0]]
  
          except Exception:
              qgndj = np.empty(0)
  
          # sorted positions of positive and junk images (0 based)
          pos = np.arange(ranks.shape[0])[np.in1d(ranks[:, i], qgnd)]
          junk = np.arange(ranks.shape[0])[np.in1d(ranks[:, i], qgndj)]
  
          k = 0
          ij = 0
          if len(junk):
              # decrease positions of positives based on the number of
              # junk images appearing before them
              ip = 0
              while ip < len(pos):
                  while ij < len(junk) and pos[ip] > junk[ij]:
                      k += 1
                      ij += 1
                  pos[ip] = pos[ip] - k
                  ip += 1
  
          # compute ap
          ap = compute_ap(pos, len(qgnd))
          map = map + ap
          aps[i] = ap
  
          # compute precision @ k
          pos += 1  # get it to 1-based
          for j in np.arange(len(kappas)):
              kq = min(max(pos), kappas[j])
              prs[i, j] = (pos <= kq).sum() / kq
          pr = pr + prs[i, :]
  
      map = map / (nq - nempty)
      pr = pr / (nq - nempty)
  
      return map, aps, pr, prs
  
imports: import numpy
label_desc: Use image node_id 3 for calling a global function with example usage: compute_map(ranks, gnd, kappas) and returns: map,  aps,  pr,  prs