code: def _init_from_npy2d(self, mat, missing, nthread):
          
          if len(mat.shape) != 2:
              raise ValueError('Input numpy.ndarray must be 2 dimensional')
          # flatten the array by rows and ensure it is float32.
          # we try to avoid data copies if possible (reshape returns a view when possible
          # and we explicitly tell np.array to try and avoid copying)
          data = np.array(mat.reshape(mat.size), copy=False, dtype=np.float32)
          handle = ctypes.c_void_p()
          missing = missing if missing is not None else np.nan
          if nthread is None:
              _check_call(_LIB.XGDMatrixCreateFromMat(
                  data.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
                  c_bst_ulong(mat.shape[0]),
                  c_bst_ulong(mat.shape[1]),
                  ctypes.c_float(missing),
                  ctypes.byref(handle)))
          else:
              _check_call(_LIB.XGDMatrixCreateFromMat_omp(
                  data.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
                  c_bst_ulong(mat.shape[0]),
                  c_bst_ulong(mat.shape[1]),
                  ctypes.c_float(missing),
                  ctypes.byref(handle),
                  nthread))
          self.handle = handle
docs: Initialize data from a 2-D numpy matrix.
  
          If ``mat`` does not have ``order='C'`` (aka row-major) or is not contiguous,
          a temporary copy will be made.
  
          If ``mat`` does not have ``dtype=numpy.float32``, a temporary copy will be made.
  
          So there could be as many as two temporary data copies; be mindful of input layout
          and type if memory use is a concern.