code: def matrix_to_pair_dictionary(
      X, row_keys=None, column_keys=None, filter_fn=None
  ):
      """
      X : numpy.ndarray
  
      row_keys : dict
          Dictionary mapping indices to row names. If omitted then maps each
          number to its string representation, such as 1 -> "1".
  
      column_keys : dict
          If omitted and matrix is square, then use the same dictionary
          as the rows. Otherwise map each column index to its string form.
  
      filter_fn : function
          If given then only add elements for which this function returns True.
      """
      n_rows, n_cols = X.shape
  
      if row_keys is None:
          row_keys = {i: i for i in range(n_rows)}
  
      if column_keys is None:
          if n_rows == n_cols:
              column_keys = row_keys
          else:
              column_keys = {j: j for j in range(n_cols)}
  
      if len(row_keys) != n_rows:
          raise ValueError(
              "Need %d row keys but got list of length %d"
              % (n_rows, len(row_keys))
          )
  
      if len(column_keys) != n_cols:
          raise ValueError(
              "Need %d column keys but got list of length %d"
              % (n_cols, len(column_keys))
          )
  
      result_dict = {}
      for i, X_i in enumerate(X):
          row_key = row_keys[i]
          for j, X_ij in enumerate(X_i):
              if filter_fn and not filter_fn(X_ij):
                  continue
              column_key = column_keys[j]
              key_pair = (row_key, column_key)
              result_dict[key_pair] = X_ij
      return result_dict
  
imports: from collections import defaultdict
  import numpy
  from scipy.sparse import dok_matrix
label_desc: Use image node_id 9 for calling a global function with example usage: matrix_to_pair_dictionary(X, row_keys, column_keys, filter_fn) and returns: result_dict