code: def _row_sparse_ndarray_from_definition(data, indices, shape=None, ctx=None,
                                          dtype=None, indices_type=None):
      
      storage_type = 'row_sparse'
      # context
      ctx = current_context() if ctx is None else ctx
      # types
      dtype = _prepare_default_dtype(data, dtype)
      indices_type = _STORAGE_AUX_TYPES[storage_type][0] if indices_type is None else indices_type
      # prepare src array and types
      data = _prepare_src_array(data, dtype)
      indices = _prepare_src_array(indices, indices_type)
  
      # TODO(junwu): Convert data, indptr, and indices to mxnet NDArrays
      # if they are not for now. In the future, we should provide a c-api
      # to accept np.ndarray types to copy from to result.data and aux_data
      if not isinstance(data, NDArray):
          data = _array(data, ctx, dtype)
      if not isinstance(indices, NDArray):
          indices = _array(indices, ctx, indices_type)
      if shape is None:
          num_indices = indices.shape[0]
          if num_indices == 0:
              raise ValueError('invalid shape')
          dim0 = indices[num_indices - 1].asscalar() + 1
          shape = (dim0, ) + data.shape[1:]
      # verify shapes
      if data.ndim != len(shape) or indices.ndim != 1 or np.prod(shape[1:]) == 0:
          raise ValueError("invalid shape")
      result = RowSparseNDArray(_new_alloc_handle(storage_type, shape, ctx, False, dtype,
                                                  [indices_type], [indices.shape]))
      check_call(_LIB.MXNDArraySyncCopyFromNDArray(result.handle, data.handle, ctypes.c_int(-1)))
      check_call(_LIB.MXNDArraySyncCopyFromNDArray(result.handle, indices.handle, ctypes.c_int(0)))
      return result
docs: Create a `RowSparseNDArray` based on data and indices