def _get_top_k_similar_rows(
      self, x, k: int, use_recency: bool = True, use_importance: bool = True
  ):
    """Returns the top k most similar rows to an input vector x.

    Args:
      x: The input vector.
      k: The number of rows to return.
      use_recency: if true then weight similarity by recency
      use_importance: if true then weight similarity by importance

    Returns:
      Rows, sorted by cosine similarity in descending order.
    """
    with self._memory_bank_lock:
      cosine_similarities = self._memory_bank['embedding'].apply(
          lambda y: np.dot(x, y)
      )

      similarity_score = cosine_similarities

      if use_recency:
        max_time = self._memory_bank['time'].max()
        discounted_time = self._memory_bank['time'].apply(
            lambda y: 0.99 ** ((max_time - y) / datetime.timedelta(minutes=1))
        )
        similarity_score += discounted_time

      if use_importance:
        importance = self._memory_bank['importance']
        similarity_score += importance

      # Sort the similarities in descending order.
      similarity_score.sort_values(ascending=False, inplace=True)

      # Return the top k rows.
      return self._memory_bank.iloc[similarity_score.head(k).index]
Returns the top k most similar rows to an input vector x.

    Args:
      x: The input vector.
      k: The number of rows to return.
      use_recency: if true then weight similarity by recency
      use_importance: if true then weight similarity by importance

    Returns:
      Rows, sorted by cosine similarity in descending order.
    
concordia/associative_memory/deprecated/associative_memory.py