Generated by Cython 0.29.36

Yellow lines hint at Python interaction.
Click on a line that starts with a "+" to see the C code that Cython generated for it.

Raw output: rank.c

+001: """
  __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 002: Functions for ranking and sorting.
 003: """
 004: cimport cython
 005: cimport numpy as np
 006: 
+007: import numpy as np
  __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 7, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 008: from cpython cimport bool
+009: from scipy.stats import rankdata
  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 9, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_INCREF(__pyx_n_s_rankdata);
  __Pyx_GIVEREF(__pyx_n_s_rankdata);
  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_rankdata);
  __pyx_t_2 = __Pyx_Import(__pyx_n_s_scipy_stats, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 9, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_rankdata); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 9, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_rankdata, __pyx_t_1) < 0) __PYX_ERR(0, 9, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+010: from zipline.utils.numpy_utils import is_missing
  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 10, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_INCREF(__pyx_n_s_is_missing);
  __Pyx_GIVEREF(__pyx_n_s_is_missing);
  PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_is_missing);
  __pyx_t_1 = __Pyx_Import(__pyx_n_s_zipline_utils_numpy_utils, __pyx_t_2, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 10, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_is_missing); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 10, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_is_missing, __pyx_t_2) < 0) __PYX_ERR(0, 10, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 011: 
 012: 
+013: np.import_array()
  __pyx_t_3 = __pyx_f_5numpy_import_array(); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 13, __pyx_L1_error)
 014: 
+015: def rankdata_1d_descending(np.ndarray data, str method):
/* Python wrapper */
static PyObject *__pyx_pw_7zipline_3lib_4rank_1rankdata_1d_descending(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_7zipline_3lib_4rank_rankdata_1d_descending[] = "\n    1D descending version of scipy.stats.rankdata.\n    ";
static PyMethodDef __pyx_mdef_7zipline_3lib_4rank_1rankdata_1d_descending = {"rankdata_1d_descending", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7zipline_3lib_4rank_1rankdata_1d_descending, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7zipline_3lib_4rank_rankdata_1d_descending};
static PyObject *__pyx_pw_7zipline_3lib_4rank_1rankdata_1d_descending(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyArrayObject *__pyx_v_data = 0;
  PyObject *__pyx_v_method = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("rankdata_1d_descending (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_method,0};
    PyObject* values[2] = {0,0};
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_method)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("rankdata_1d_descending", 1, 2, 2, 1); __PYX_ERR(0, 15, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "rankdata_1d_descending") < 0)) __PYX_ERR(0, 15, __pyx_L3_error)
      }
    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
    }
    __pyx_v_data = ((PyArrayObject *)values[0]);
    __pyx_v_method = ((PyObject*)values[1]);
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("rankdata_1d_descending", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 15, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("zipline.lib.rank.rankdata_1d_descending", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_data), __pyx_ptype_5numpy_ndarray, 1, "data", 0))) __PYX_ERR(0, 15, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_method), (&PyUnicode_Type), 1, "method", 1))) __PYX_ERR(0, 15, __pyx_L1_error)
  __pyx_r = __pyx_pf_7zipline_3lib_4rank_rankdata_1d_descending(__pyx_self, __pyx_v_data, __pyx_v_method);
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7zipline_3lib_4rank_rankdata_1d_descending(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_data, PyObject *__pyx_v_method) {
  PyObject *__pyx_r = NULL;
  __Pyx_TraceDeclarations
  __Pyx_TraceFrameInit(__pyx_codeobj_)
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("rankdata_1d_descending", 0);
  __Pyx_TraceCall("rankdata_1d_descending", __pyx_f[0], 15, 0, __PYX_ERR(0, 15, __pyx_L1_error));
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_AddTraceback("zipline.lib.rank.rankdata_1d_descending", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_TraceReturn(__pyx_r, 0);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__30 = PyTuple_Pack(2, __pyx_n_s_data, __pyx_n_s_method); if (unlikely(!__pyx_tuple__30)) __PYX_ERR(0, 15, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__30);
  __Pyx_GIVEREF(__pyx_tuple__30);
/* … */
  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7zipline_3lib_4rank_1rankdata_1d_descending, NULL, __pyx_n_s_zipline_lib_rank); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 15, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_rankdata_1d_descending, __pyx_t_1) < 0) __PYX_ERR(0, 15, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_codeobj_ = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__30, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_zipline_lib_rank_pyx, __pyx_n_s_rankdata_1d_descending, 15, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj_)) __PYX_ERR(0, 15, __pyx_L1_error)
 016:     """
 017:     1D descending version of scipy.stats.rankdata.
 018:     """
+019:     return rankdata(-(data.view(np.float64)), method=method)
  __Pyx_XDECREF(__pyx_r);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_rankdata); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 19, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_data), __pyx_n_s_view); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 19, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 19, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 19, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = NULL;
  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_4)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_4);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
    }
  }
  __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5);
  __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 19, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = PyNumber_Negative(__pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 19, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 19, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_GIVEREF(__pyx_t_3);
  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
  __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 19, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_method, __pyx_v_method) < 0) __PYX_ERR(0, 19, __pyx_L1_error)
  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 19, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_r = __pyx_t_5;
  __pyx_t_5 = 0;
  goto __pyx_L0;
 020: 
 021: 
+022: def masked_rankdata_2d(np.ndarray data,
/* Python wrapper */
static PyObject *__pyx_pw_7zipline_3lib_4rank_3masked_rankdata_2d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_7zipline_3lib_4rank_2masked_rankdata_2d[] = "\n    Compute masked rankdata on data on float64, int64, or datetime64 data.\n    ";
static PyMethodDef __pyx_mdef_7zipline_3lib_4rank_3masked_rankdata_2d = {"masked_rankdata_2d", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7zipline_3lib_4rank_3masked_rankdata_2d, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7zipline_3lib_4rank_2masked_rankdata_2d};
static PyObject *__pyx_pw_7zipline_3lib_4rank_3masked_rankdata_2d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyArrayObject *__pyx_v_data = 0;
  PyArrayObject *__pyx_v_mask = 0;
  PyObject *__pyx_v_missing_value = 0;
  PyObject *__pyx_v_method = 0;
  PyBoolObject *__pyx_v_ascending = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("masked_rankdata_2d (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_mask,&__pyx_n_s_missing_value,&__pyx_n_s_method,&__pyx_n_s_ascending,0};
    PyObject* values[5] = {0,0,0,0,0};
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
        CYTHON_FALLTHROUGH;
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("masked_rankdata_2d", 1, 5, 5, 1); __PYX_ERR(0, 22, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_missing_value)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("masked_rankdata_2d", 1, 5, 5, 2); __PYX_ERR(0, 22, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_method)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("masked_rankdata_2d", 1, 5, 5, 3); __PYX_ERR(0, 22, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  4:
        if (likely((values[4] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ascending)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("masked_rankdata_2d", 1, 5, 5, 4); __PYX_ERR(0, 22, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "masked_rankdata_2d") < 0)) __PYX_ERR(0, 22, __pyx_L3_error)
      }
    } else if (PyTuple_GET_SIZE(__pyx_args) != 5) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
      values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
    }
    __pyx_v_data = ((PyArrayObject *)values[0]);
    __pyx_v_mask = ((PyArrayObject *)values[1]);
    __pyx_v_missing_value = values[2];
    __pyx_v_method = ((PyObject*)values[3]);
    __pyx_v_ascending = ((PyBoolObject *)values[4]);
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("masked_rankdata_2d", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 22, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("zipline.lib.rank.masked_rankdata_2d", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_data), __pyx_ptype_5numpy_ndarray, 1, "data", 0))) __PYX_ERR(0, 22, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mask), __pyx_ptype_5numpy_ndarray, 1, "mask", 0))) __PYX_ERR(0, 23, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_method), (&PyUnicode_Type), 1, "method", 1))) __PYX_ERR(0, 25, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ascending), __pyx_ptype_7cpython_4bool_bool, 1, "ascending", 0))) __PYX_ERR(0, 26, __pyx_L1_error)
  __pyx_r = __pyx_pf_7zipline_3lib_4rank_2masked_rankdata_2d(__pyx_self, __pyx_v_data, __pyx_v_mask, __pyx_v_missing_value, __pyx_v_method, __pyx_v_ascending);
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7zipline_3lib_4rank_2masked_rankdata_2d(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_data, PyArrayObject *__pyx_v_mask, PyObject *__pyx_v_missing_value, PyObject *__pyx_v_method, PyBoolObject *__pyx_v_ascending) {
  PyObject *__pyx_v_dtype_name = 0;
  PyArrayObject *__pyx_v_missing_locations = 0;
  PyObject *__pyx_v_result = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_TraceDeclarations
  __Pyx_TraceFrameInit(__pyx_codeobj__2)
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("masked_rankdata_2d", 0);
  __Pyx_TraceCall("masked_rankdata_2d", __pyx_f[0], 22, 0, __PYX_ERR(0, 22, __pyx_L1_error));
  __Pyx_INCREF((PyObject *)__pyx_v_data);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_8);
  __Pyx_XDECREF(__pyx_t_10);
  __Pyx_AddTraceback("zipline.lib.rank.masked_rankdata_2d", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_dtype_name);
  __Pyx_XDECREF((PyObject *)__pyx_v_missing_locations);
  __Pyx_XDECREF(__pyx_v_result);
  __Pyx_XDECREF((PyObject *)__pyx_v_data);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_TraceReturn(__pyx_r, 0);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__31 = PyTuple_Pack(8, __pyx_n_s_data, __pyx_n_s_mask, __pyx_n_s_missing_value, __pyx_n_s_method, __pyx_n_s_ascending, __pyx_n_s_dtype_name, __pyx_n_s_missing_locations, __pyx_n_s_result); if (unlikely(!__pyx_tuple__31)) __PYX_ERR(0, 22, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__31);
  __Pyx_GIVEREF(__pyx_tuple__31);
/* … */
  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7zipline_3lib_4rank_3masked_rankdata_2d, NULL, __pyx_n_s_zipline_lib_rank); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_masked_rankdata_2d, __pyx_t_1) < 0) __PYX_ERR(0, 22, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_codeobj__2 = (PyObject*)__Pyx_PyCode_New(5, 0, 8, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__31, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_zipline_lib_rank_pyx, __pyx_n_s_masked_rankdata_2d, 22, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__2)) __PYX_ERR(0, 22, __pyx_L1_error)
 023:                        np.ndarray mask,
 024:                        object missing_value,
 025:                        str method,
 026:                        bool ascending):
 027:     """
 028:     Compute masked rankdata on data on float64, int64, or datetime64 data.
 029:     """
+030:     cdef str dtype_name = data.dtype.name
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_data), __pyx_n_s_dtype); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 30, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 30, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (!(likely(PyUnicode_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||((void)PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 30, __pyx_L1_error)
  __pyx_v_dtype_name = ((PyObject*)__pyx_t_2);
  __pyx_t_2 = 0;
+031:     if dtype_name not in ('float64', 'int64', 'datetime64[ns]'):
  __Pyx_INCREF(__pyx_v_dtype_name);
  __pyx_t_3 = __pyx_v_dtype_name;
  __pyx_t_5 = (__Pyx_PyUnicode_Equals(__pyx_t_3, __pyx_n_u_float64, Py_NE)); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 31, __pyx_L1_error)
  __pyx_t_6 = (__pyx_t_5 != 0);
  if (__pyx_t_6) {
  } else {
    __pyx_t_4 = __pyx_t_6;
    goto __pyx_L4_bool_binop_done;
  }
  __pyx_t_6 = (__Pyx_PyUnicode_Equals(__pyx_t_3, __pyx_n_u_int64, Py_NE)); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 31, __pyx_L1_error)
  __pyx_t_5 = (__pyx_t_6 != 0);
  if (__pyx_t_5) {
  } else {
    __pyx_t_4 = __pyx_t_5;
    goto __pyx_L4_bool_binop_done;
  }
  __pyx_t_5 = (__Pyx_PyUnicode_Equals(__pyx_t_3, __pyx_kp_u_datetime64_ns, Py_NE)); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 31, __pyx_L1_error)
  __pyx_t_6 = (__pyx_t_5 != 0);
  __pyx_t_4 = __pyx_t_6;
  __pyx_L4_bool_binop_done:;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_6 = (__pyx_t_4 != 0);
  if (unlikely(__pyx_t_6)) {
/* … */
  }
+032:         raise TypeError(
    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 32, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __PYX_ERR(0, 32, __pyx_L1_error)
+033:             "Can't compute rankdata on array of dtype %r." % dtype_name
    __pyx_t_2 = PyUnicode_Format(__pyx_kp_u_Can_t_compute_rankdata_on_array, __pyx_v_dtype_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 33, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
 034:         )
 035: 
+036:     cdef np.ndarray missing_locations = (~mask | is_missing(data, missing_value))
  __pyx_t_1 = PyNumber_Invert(((PyObject *)__pyx_v_mask)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 36, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_is_missing); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 36, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __pyx_t_8 = NULL;
  __pyx_t_9 = 0;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_7))) {
    __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7);
    if (likely(__pyx_t_8)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
      __Pyx_INCREF(__pyx_t_8);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_7, function);
      __pyx_t_9 = 1;
    }
  }
  #if CYTHON_FAST_PYCALL
  if (PyFunction_Check(__pyx_t_7)) {
    PyObject *__pyx_temp[3] = {__pyx_t_8, ((PyObject *)__pyx_v_data), __pyx_v_missing_value};
    __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 36, __pyx_L1_error)
    __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
    __Pyx_GOTREF(__pyx_t_2);
  } else
  #endif
  #if CYTHON_FAST_PYCCALL
  if (__Pyx_PyFastCFunction_Check(__pyx_t_7)) {
    PyObject *__pyx_temp[3] = {__pyx_t_8, ((PyObject *)__pyx_v_data), __pyx_v_missing_value};
    __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 36, __pyx_L1_error)
    __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
    __Pyx_GOTREF(__pyx_t_2);
  } else
  #endif
  {
    __pyx_t_10 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 36, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_10);
    if (__pyx_t_8) {
      __Pyx_GIVEREF(__pyx_t_8); PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_8); __pyx_t_8 = NULL;
    }
    __Pyx_INCREF(((PyObject *)__pyx_v_data));
    __Pyx_GIVEREF(((PyObject *)__pyx_v_data));
    PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_9, ((PyObject *)__pyx_v_data));
    __Pyx_INCREF(__pyx_v_missing_value);
    __Pyx_GIVEREF(__pyx_v_missing_value);
    PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_9, __pyx_v_missing_value);
    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_10, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 36, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
  }
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
  __pyx_t_7 = PyNumber_Or(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 36, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (!(likely(((__pyx_t_7) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_7, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 36, __pyx_L1_error)
  __pyx_v_missing_locations = ((PyArrayObject *)__pyx_t_7);
  __pyx_t_7 = 0;
 037: 
 038:     # Interpret the bytes of integral data as floats for sorting.
+039:     data = data.copy().view(np.float64)
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_data), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 39, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_10 = NULL;
  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) {
    __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_1);
    if (likely(__pyx_t_10)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
      __Pyx_INCREF(__pyx_t_10);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_1, function);
    }
  }
  __pyx_t_2 = (__pyx_t_10) ? __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_10) : __Pyx_PyObject_CallNoArg(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 39, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_view); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 39, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 39, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_float64); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 39, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_10);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = NULL;
  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) {
    __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_1);
    if (likely(__pyx_t_2)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
      __Pyx_INCREF(__pyx_t_2);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_1, function);
    }
  }
  __pyx_t_7 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_2, __pyx_t_10) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_10);
  __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
  if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 39, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (!(likely(((__pyx_t_7) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_7, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 39, __pyx_L1_error)
  __Pyx_DECREF_SET(__pyx_v_data, ((PyArrayObject *)__pyx_t_7));
  __pyx_t_7 = 0;
+040:     data[missing_locations] = np.nan
  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_np); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 40, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_nan); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 40, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
  if (unlikely(PyObject_SetItem(((PyObject *)__pyx_v_data), ((PyObject *)__pyx_v_missing_locations), __pyx_t_1) < 0)) __PYX_ERR(0, 40, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+041:     if not ascending:
  __pyx_t_6 = __Pyx_PyObject_IsTrue(((PyObject *)__pyx_v_ascending)); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 41, __pyx_L1_error)
  __pyx_t_4 = ((!__pyx_t_6) != 0);
  if (__pyx_t_4) {
/* … */
  }
+042:         data = -data
    __pyx_t_1 = PyNumber_Negative(((PyObject *)__pyx_v_data)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 42, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 42, __pyx_L1_error)
    __Pyx_DECREF_SET(__pyx_v_data, ((PyArrayObject *)__pyx_t_1));
    __pyx_t_1 = 0;
 043: 
 044:     # OPTIMIZATION: Fast path the default case with our own specialized
 045:     # Cython implementation.
+046:     if method == 'ordinal':
  __pyx_t_4 = (__Pyx_PyUnicode_Equals(__pyx_v_method, __pyx_n_u_ordinal, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 46, __pyx_L1_error)
  __pyx_t_6 = (__pyx_t_4 != 0);
  if (__pyx_t_6) {
/* … */
    goto __pyx_L8;
  }
+047:         result = rankdata_2d_ordinal(data)
    __pyx_t_1 = __pyx_f_7zipline_3lib_4rank_rankdata_2d_ordinal(((PyArrayObject *)__pyx_v_data), 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 47, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_v_result = __pyx_t_1;
    __pyx_t_1 = 0;
 048:     else:
 049:         # FUTURE OPTIMIZATION:
 050:         # Write a less general "apply to rows" method that doesn't do all
 051:         # the extra work that apply_along_axis does.
+052:         result = np.apply_along_axis(rankdata, 1, data, method=method)
  /*else*/ {
    __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 52, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_apply_along_axis); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 52, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_rankdata); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 52, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_10 = PyTuple_New(3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 52, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_10);
    __Pyx_GIVEREF(__pyx_t_1);
    PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_1);
    __Pyx_INCREF(__pyx_int_1);
    __Pyx_GIVEREF(__pyx_int_1);
    PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_int_1);
    __Pyx_INCREF(((PyObject *)__pyx_v_data));
    __Pyx_GIVEREF(((PyObject *)__pyx_v_data));
    PyTuple_SET_ITEM(__pyx_t_10, 2, ((PyObject *)__pyx_v_data));
    __pyx_t_1 = 0;
    __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 52, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_method, __pyx_v_method) < 0) __PYX_ERR(0, 52, __pyx_L1_error)
    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_10, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 52, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_v_result = __pyx_t_2;
    __pyx_t_2 = 0;
 053: 
 054:         # On SciPy >= 0.17, rankdata returns integers for any method except
 055:         # average.
+056:         if result.dtype.name != 'float64':
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_result, __pyx_n_s_dtype); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 56, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 56, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_6 = (__Pyx_PyUnicode_Equals(__pyx_t_1, __pyx_n_u_float64, Py_NE)); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 56, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (__pyx_t_6) {
/* … */
    }
  }
  __pyx_L8:;
+057:             result = result.astype('float64')
      __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_result, __pyx_n_s_astype); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_10 = NULL;
      if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
        __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_2);
        if (likely(__pyx_t_10)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
          __Pyx_INCREF(__pyx_t_10);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_2, function);
        }
      }
      __pyx_t_1 = (__pyx_t_10) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_10, __pyx_n_u_float64) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_n_u_float64);
      __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
      if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 57, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __Pyx_DECREF_SET(__pyx_v_result, __pyx_t_1);
      __pyx_t_1 = 0;
 058: 
 059:     # rankdata will sort missing values into last place, but we want our nans
 060:     # to propagate, so explicitly re-apply.
+061:     result[missing_locations] = np.nan
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 61, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_nan); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 61, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (unlikely(PyObject_SetItem(__pyx_v_result, ((PyObject *)__pyx_v_missing_locations), __pyx_t_2) < 0)) __PYX_ERR(0, 61, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+062:     return result
  __Pyx_XDECREF(__pyx_r);
  __Pyx_INCREF(__pyx_v_result);
  __pyx_r = __pyx_v_result;
  goto __pyx_L0;
 063: 
 064: 
 065: @cython.boundscheck(False)
 066: @cython.wraparound(False)
 067: @cython.embedsignature(True)
+068: cpdef rankdata_2d_ordinal(np.ndarray[np.float64_t, ndim=2] array):
static PyObject *__pyx_pw_7zipline_3lib_4rank_5rankdata_2d_ordinal(PyObject *__pyx_self, PyObject *__pyx_v_array); /*proto*/
static PyObject *__pyx_f_7zipline_3lib_4rank_rankdata_2d_ordinal(PyArrayObject *__pyx_v_array, CYTHON_UNUSED int __pyx_skip_dispatch) {
  Py_ssize_t __pyx_v_nrows;
  Py_ssize_t __pyx_v_ncols;
  __Pyx_memviewslice __pyx_v_sort_idxs = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyArrayObject *__pyx_v_out = 0;
  Py_ssize_t __pyx_v_i;
  Py_ssize_t __pyx_v_j;
  __Pyx_LocalBuf_ND __pyx_pybuffernd_array;
  __Pyx_Buffer __pyx_pybuffer_array;
  __Pyx_LocalBuf_ND __pyx_pybuffernd_out;
  __Pyx_Buffer __pyx_pybuffer_out;
  PyObject *__pyx_r = NULL;
  __Pyx_TraceDeclarations
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("rankdata_2d_ordinal", 0);
  __Pyx_TraceCall("rankdata_2d_ordinal", __pyx_f[0], 68, 0, __PYX_ERR(0, 68, __pyx_L1_error));
  __pyx_pybuffer_out.pybuffer.buf = NULL;
  __pyx_pybuffer_out.refcount = 0;
  __pyx_pybuffernd_out.data = NULL;
  __pyx_pybuffernd_out.rcbuffer = &__pyx_pybuffer_out;
  __pyx_pybuffer_array.pybuffer.buf = NULL;
  __pyx_pybuffer_array.refcount = 0;
  __pyx_pybuffernd_array.data = NULL;
  __pyx_pybuffernd_array.rcbuffer = &__pyx_pybuffer_array;
  {
    __Pyx_BufFmt_StackElem __pyx_stack[1];
    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_array.rcbuffer->pybuffer, (PyObject*)__pyx_v_array, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 68, __pyx_L1_error)
  }
  __pyx_pybuffernd_array.diminfo[0].strides = __pyx_pybuffernd_array.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_array.diminfo[0].shape = __pyx_pybuffernd_array.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_array.diminfo[1].strides = __pyx_pybuffernd_array.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_array.diminfo[1].shape = __pyx_pybuffernd_array.rcbuffer->pybuffer.shape[1];
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __PYX_XDEC_MEMVIEW(&__pyx_t_2, 1);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_PyThreadState_declare
    __Pyx_PyThreadState_assign
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_array.rcbuffer->pybuffer);
    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out.rcbuffer->pybuffer);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("zipline.lib.rank.rankdata_2d_ordinal", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = 0;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_array.rcbuffer->pybuffer);
  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out.rcbuffer->pybuffer);
  __pyx_L2:;
  __PYX_XDEC_MEMVIEW(&__pyx_v_sort_idxs, 1);
  __Pyx_XDECREF((PyObject *)__pyx_v_out);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_TraceReturn(__pyx_r, 0);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* Python wrapper */
static PyObject *__pyx_pw_7zipline_3lib_4rank_5rankdata_2d_ordinal(PyObject *__pyx_self, PyObject *__pyx_v_array); /*proto*/
static char __pyx_doc_7zipline_3lib_4rank_4rankdata_2d_ordinal[] = "rankdata_2d_ordinal(ndarray array)\n\n    Equivalent to:\n    numpy.apply_over_axis(scipy.stats.rankdata, 1, array, method='ordinal')\n    ";
static PyObject *__pyx_pw_7zipline_3lib_4rank_5rankdata_2d_ordinal(PyObject *__pyx_self, PyObject *__pyx_v_array) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("rankdata_2d_ordinal (wrapper)", 0);
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_array), __pyx_ptype_5numpy_ndarray, 1, "array", 0))) __PYX_ERR(0, 68, __pyx_L1_error)
  __pyx_r = __pyx_pf_7zipline_3lib_4rank_4rankdata_2d_ordinal(__pyx_self, ((PyArrayObject *)__pyx_v_array));
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7zipline_3lib_4rank_4rankdata_2d_ordinal(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_array) {
  __Pyx_LocalBuf_ND __pyx_pybuffernd_array;
  __Pyx_Buffer __pyx_pybuffer_array;
  PyObject *__pyx_r = NULL;
  __Pyx_TraceDeclarations
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("rankdata_2d_ordinal", 0);
  __Pyx_TraceCall("rankdata_2d_ordinal (wrapper)", __pyx_f[0], 68, 0, __PYX_ERR(0, 68, __pyx_L1_error));
  __pyx_pybuffer_array.pybuffer.buf = NULL;
  __pyx_pybuffer_array.refcount = 0;
  __pyx_pybuffernd_array.data = NULL;
  __pyx_pybuffernd_array.rcbuffer = &__pyx_pybuffer_array;
  {
    __Pyx_BufFmt_StackElem __pyx_stack[1];
    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_array.rcbuffer->pybuffer, (PyObject*)__pyx_v_array, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 68, __pyx_L1_error)
  }
  __pyx_pybuffernd_array.diminfo[0].strides = __pyx_pybuffernd_array.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_array.diminfo[0].shape = __pyx_pybuffernd_array.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_array.diminfo[1].strides = __pyx_pybuffernd_array.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_array.diminfo[1].shape = __pyx_pybuffernd_array.rcbuffer->pybuffer.shape[1];
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_1 = __pyx_f_7zipline_3lib_4rank_rankdata_2d_ordinal(__pyx_v_array, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 68, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_PyThreadState_declare
    __Pyx_PyThreadState_assign
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_array.rcbuffer->pybuffer);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("zipline.lib.rank.rankdata_2d_ordinal", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_array.rcbuffer->pybuffer);
  __pyx_L2:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_TraceReturn(__pyx_r, 0);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 069:     """
 070:     Equivalent to:
 071:     numpy.apply_over_axis(scipy.stats.rankdata, 1, array, method='ordinal')
 072:     """
 073:     cdef:
+074:         Py_ssize_t nrows = np.PyArray_DIMS(array)[0]
  __pyx_v_nrows = (PyArray_DIMS(((PyArrayObject *)__pyx_v_array))[0]);
+075:         Py_ssize_t ncols = np.PyArray_DIMS(array)[1]
  __pyx_v_ncols = (PyArray_DIMS(((PyArrayObject *)__pyx_v_array))[1]);
 076:         Py_ssize_t[:, ::1] sort_idxs
 077:         np.ndarray[np.float64_t, ndim=2] out
 078: 
 079:     # scipy.stats.rankdata explicitly uses MERGESORT instead of QUICKSORT for
 080:     # the ordinal branch.  c.f. commit ab21d2fee2d27daca0b2c161bbb7dba7e73e70ba
+081:     sort_idxs = np.PyArray_ArgSort(array, 1, np.NPY_MERGESORT)
  __pyx_t_1 = PyArray_ArgSort(((PyArrayObject *)__pyx_v_array), 1, NPY_MERGESORT); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 81, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_Py_ssize_t(__pyx_t_1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_2.memview)) __PYX_ERR(0, 81, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_sort_idxs = __pyx_t_2;
  __pyx_t_2.memview = NULL;
  __pyx_t_2.data = NULL;
 082: 
 083:     # Roughly, "out = np.empty_like(array)"
+084:     out = np.PyArray_EMPTY(2, np.PyArray_DIMS(array), np.NPY_DOUBLE, False)
  __pyx_t_1 = PyArray_EMPTY(2, PyArray_DIMS(((PyArrayObject *)__pyx_v_array)), NPY_DOUBLE, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 84, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 84, __pyx_L1_error)
  __pyx_t_3 = ((PyArrayObject *)__pyx_t_1);
  {
    __Pyx_BufFmt_StackElem __pyx_stack[1];
    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out.rcbuffer->pybuffer);
    __pyx_t_4 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out.rcbuffer->pybuffer, (PyObject*)__pyx_t_3, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack);
    if (unlikely(__pyx_t_4 < 0)) {
      PyErr_Fetch(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7);
      if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out.rcbuffer->pybuffer, (PyObject*)__pyx_v_out, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack) == -1)) {
        Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_6); Py_XDECREF(__pyx_t_7);
        __Pyx_RaiseBufferFallbackError();
      } else {
        PyErr_Restore(__pyx_t_5, __pyx_t_6, __pyx_t_7);
      }
      __pyx_t_5 = __pyx_t_6 = __pyx_t_7 = 0;
    }
    __pyx_pybuffernd_out.diminfo[0].strides = __pyx_pybuffernd_out.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out.diminfo[0].shape = __pyx_pybuffernd_out.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_out.diminfo[1].strides = __pyx_pybuffernd_out.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_out.diminfo[1].shape = __pyx_pybuffernd_out.rcbuffer->pybuffer.shape[1];
    if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 84, __pyx_L1_error)
  }
  __pyx_t_3 = 0;
  __pyx_v_out = ((PyArrayObject *)__pyx_t_1);
  __pyx_t_1 = 0;
 085: 
 086:     cdef Py_ssize_t i
 087:     cdef Py_ssize_t j
 088: 
+089:     for i in range(nrows):
  __pyx_t_8 = __pyx_v_nrows;
  __pyx_t_9 = __pyx_t_8;
  for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
    __pyx_v_i = __pyx_t_10;
+090:         for j in range(ncols):
    __pyx_t_11 = __pyx_v_ncols;
    __pyx_t_12 = __pyx_t_11;
    for (__pyx_t_13 = 0; __pyx_t_13 < __pyx_t_12; __pyx_t_13+=1) {
      __pyx_v_j = __pyx_t_13;
+091:             out[i, sort_idxs[i, j]] = j + 1.0
      __pyx_t_14 = __pyx_v_i;
      __pyx_t_15 = __pyx_v_j;
      __pyx_t_16 = __pyx_v_i;
      __pyx_t_17 = (*((Py_ssize_t *) ( /* dim=1 */ ((char *) (((Py_ssize_t *) ( /* dim=0 */ (__pyx_v_sort_idxs.data + __pyx_t_14 * __pyx_v_sort_idxs.strides[0]) )) + __pyx_t_15)) )));
      *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_out.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_out.diminfo[0].strides, __pyx_t_17, __pyx_pybuffernd_out.diminfo[1].strides) = (__pyx_v_j + 1.0);
    }
  }
 092: 
+093:     return out
  __Pyx_XDECREF(__pyx_r);
  __Pyx_INCREF(((PyObject *)__pyx_v_out));
  __pyx_r = ((PyObject *)__pyx_v_out);
  goto __pyx_L0;
 094: 
 095: 
 096: @cython.embedsignature(True)
+097: cpdef grouped_masked_is_maximal(np.ndarray[np.int64_t, ndim=2] data,
static PyObject *__pyx_pw_7zipline_3lib_4rank_7grouped_masked_is_maximal(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyObject *__pyx_f_7zipline_3lib_4rank_grouped_masked_is_maximal(PyArrayObject *__pyx_v_data, __Pyx_memviewslice __pyx_v_groupby, __Pyx_memviewslice __pyx_v_mask, CYTHON_UNUSED int __pyx_skip_dispatch) {
  Py_ssize_t __pyx_v_i;
  Py_ssize_t __pyx_v_j;
  __pyx_t_5numpy_int64_t __pyx_v_group;
  __pyx_t_5numpy_int64_t __pyx_v_value;
  PyArrayObject *__pyx_v_out = 0;
  PyObject *__pyx_v_best_per_group = 0;
  Py_ssize_t __pyx_v_nrows;
  Py_ssize_t __pyx_v_ncols;
  __Pyx_LocalBuf_ND __pyx_pybuffernd_data;
  __Pyx_Buffer __pyx_pybuffer_data;
  __Pyx_LocalBuf_ND __pyx_pybuffernd_out;
  __Pyx_Buffer __pyx_pybuffer_out;
  PyObject *__pyx_r = NULL;
  __Pyx_TraceDeclarations
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("grouped_masked_is_maximal", 0);
  __Pyx_TraceCall("grouped_masked_is_maximal", __pyx_f[0], 97, 0, __PYX_ERR(0, 97, __pyx_L1_error));
  __pyx_pybuffer_out.pybuffer.buf = NULL;
  __pyx_pybuffer_out.refcount = 0;
  __pyx_pybuffernd_out.data = NULL;
  __pyx_pybuffernd_out.rcbuffer = &__pyx_pybuffer_out;
  __pyx_pybuffer_data.pybuffer.buf = NULL;
  __pyx_pybuffer_data.refcount = 0;
  __pyx_pybuffernd_data.data = NULL;
  __pyx_pybuffernd_data.rcbuffer = &__pyx_pybuffer_data;
  {
    __Pyx_BufFmt_StackElem __pyx_stack[1];
    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_data.rcbuffer->pybuffer, (PyObject*)__pyx_v_data, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 97, __pyx_L1_error)
  }
  __pyx_pybuffernd_data.diminfo[0].strides = __pyx_pybuffernd_data.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_data.diminfo[0].shape = __pyx_pybuffernd_data.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_data.diminfo[1].strides = __pyx_pybuffernd_data.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_data.diminfo[1].shape = __pyx_pybuffernd_data.rcbuffer->pybuffer.shape[1];
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_8);
  __Pyx_XDECREF(__pyx_t_10);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_PyThreadState_declare
    __Pyx_PyThreadState_assign
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_data.rcbuffer->pybuffer);
    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out.rcbuffer->pybuffer);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("zipline.lib.rank.grouped_masked_is_maximal", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = 0;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_data.rcbuffer->pybuffer);
  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_out.rcbuffer->pybuffer);
  __pyx_L2:;
  __Pyx_XDECREF((PyObject *)__pyx_v_out);
  __Pyx_XDECREF(__pyx_v_best_per_group);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_TraceReturn(__pyx_r, 0);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* Python wrapper */
static PyObject *__pyx_pw_7zipline_3lib_4rank_7grouped_masked_is_maximal(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_7zipline_3lib_4rank_6grouped_masked_is_maximal[] = "grouped_masked_is_maximal(ndarray data, int64_t[:, ::1] groupby, uint8_t[:, ::1] mask)\nBuild a mask of the top value for each row in ``data``, grouped by\n    ``groupby`` and masked by ``mask``.\n    Parameters\n    ----------\n    data : np.array[np.int64_t]\n        Data on which we should find maximal values for each row.\n    groupby : np.array[np.int64_t]\n        Grouping labels for rows of ``data``. We choose one entry in each\n        row for each unique grouping key in that row.\n    mask : np.array[np.uint8_t]\n        Boolean mask of locations to consider as possible maximal values.\n        Locations with a 0 in ``mask`` are ignored.\n    Returns\n    -------\n    maximal_locations : np.array[bool]\n        Mask containing True for the maximal non-masked value in each row/group.\n    ";
static PyObject *__pyx_pw_7zipline_3lib_4rank_7grouped_masked_is_maximal(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyArrayObject *__pyx_v_data = 0;
  __Pyx_memviewslice __pyx_v_groupby = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_mask = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("grouped_masked_is_maximal (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_groupby,&__pyx_n_s_mask,0};
    PyObject* values[3] = {0,0,0};
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_groupby)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("grouped_masked_is_maximal", 1, 3, 3, 1); __PYX_ERR(0, 97, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("grouped_masked_is_maximal", 1, 3, 3, 2); __PYX_ERR(0, 97, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "grouped_masked_is_maximal") < 0)) __PYX_ERR(0, 97, __pyx_L3_error)
      }
    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
    }
    __pyx_v_data = ((PyArrayObject *)values[0]);
    __pyx_v_groupby = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_int64_t(values[1], PyBUF_WRITABLE); if (unlikely(!__pyx_v_groupby.memview)) __PYX_ERR(0, 98, __pyx_L3_error)
    __pyx_v_mask = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_uint8_t(values[2], PyBUF_WRITABLE); if (unlikely(!__pyx_v_mask.memview)) __PYX_ERR(0, 99, __pyx_L3_error)
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("grouped_masked_is_maximal", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 97, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("zipline.lib.rank.grouped_masked_is_maximal", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_data), __pyx_ptype_5numpy_ndarray, 1, "data", 0))) __PYX_ERR(0, 97, __pyx_L1_error)
  __pyx_r = __pyx_pf_7zipline_3lib_4rank_6grouped_masked_is_maximal(__pyx_self, __pyx_v_data, __pyx_v_groupby, __pyx_v_mask);
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7zipline_3lib_4rank_6grouped_masked_is_maximal(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_data, __Pyx_memviewslice __pyx_v_groupby, __Pyx_memviewslice __pyx_v_mask) {
  __Pyx_LocalBuf_ND __pyx_pybuffernd_data;
  __Pyx_Buffer __pyx_pybuffer_data;
  PyObject *__pyx_r = NULL;
  __Pyx_TraceDeclarations
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("grouped_masked_is_maximal", 0);
  __Pyx_TraceCall("grouped_masked_is_maximal (wrapper)", __pyx_f[0], 97, 0, __PYX_ERR(0, 97, __pyx_L1_error));
  __pyx_pybuffer_data.pybuffer.buf = NULL;
  __pyx_pybuffer_data.refcount = 0;
  __pyx_pybuffernd_data.data = NULL;
  __pyx_pybuffernd_data.rcbuffer = &__pyx_pybuffer_data;
  {
    __Pyx_BufFmt_StackElem __pyx_stack[1];
    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_data.rcbuffer->pybuffer, (PyObject*)__pyx_v_data, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 97, __pyx_L1_error)
  }
  __pyx_pybuffernd_data.diminfo[0].strides = __pyx_pybuffernd_data.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_data.diminfo[0].shape = __pyx_pybuffernd_data.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_data.diminfo[1].strides = __pyx_pybuffernd_data.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_data.diminfo[1].shape = __pyx_pybuffernd_data.rcbuffer->pybuffer.shape[1];
  __Pyx_XDECREF(__pyx_r);
  if (unlikely(!__pyx_v_groupby.memview)) { __Pyx_RaiseUnboundLocalError("groupby"); __PYX_ERR(0, 97, __pyx_L1_error) }
  if (unlikely(!__pyx_v_mask.memview)) { __Pyx_RaiseUnboundLocalError("mask"); __PYX_ERR(0, 97, __pyx_L1_error) }
  __pyx_t_1 = __pyx_f_7zipline_3lib_4rank_grouped_masked_is_maximal(__pyx_v_data, __pyx_v_groupby, __pyx_v_mask, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 97, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_PyThreadState_declare
    __Pyx_PyThreadState_assign
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_data.rcbuffer->pybuffer);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("zipline.lib.rank.grouped_masked_is_maximal", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_data.rcbuffer->pybuffer);
  __pyx_L2:;
  __PYX_XDEC_MEMVIEW(&__pyx_v_groupby, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_mask, 1);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_TraceReturn(__pyx_r, 0);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 098:                                 np.int64_t[:, ::1] groupby,
 099:                                 np.uint8_t[:, ::1] mask):
 100:     """Build a mask of the top value for each row in ``data``, grouped by
 101:     ``groupby`` and masked by ``mask``.
 102:     Parameters
 103:     ----------
 104:     data : np.array[np.int64_t]
 105:         Data on which we should find maximal values for each row.
 106:     groupby : np.array[np.int64_t]
 107:         Grouping labels for rows of ``data``. We choose one entry in each
 108:         row for each unique grouping key in that row.
 109:     mask : np.array[np.uint8_t]
 110:         Boolean mask of locations to consider as possible maximal values.
 111:         Locations with a 0 in ``mask`` are ignored.
 112:     Returns
 113:     -------
 114:     maximal_locations : np.array[bool]
 115:         Mask containing True for the maximal non-masked value in each row/group.
 116:     """
 117:     # Cython thinks ``.shape`` is an intp_t pointer on ndarrays, so we need to
 118:     # cast to object to get the proper shape attribute.
+119:     if not ((<object> data).shape
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_data), __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 119, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
/* … */
  __pyx_t_6 = ((!__pyx_t_5) != 0);
  if (unlikely(__pyx_t_6)) {
/* … */
  }
+120:             == (<object> groupby).shape
  __pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_groupby, 2, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_5numpy_int64_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_5numpy_int64_t, 0);; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 120, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 120, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = PyObject_RichCompare(__pyx_t_1, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 120, __pyx_L1_error)
  if (__Pyx_PyObject_IsTrue(__pyx_t_2)) {
    __Pyx_DECREF(__pyx_t_2);
/* … */
  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 120, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+121:             == (<object> data).shape):
    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_data), __pyx_n_s_shape); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 121, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_2 = PyObject_RichCompare(__pyx_t_3, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 121, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  }
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+122:         raise AssertionError(
    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_AssertionError, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 122, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __PYX_ERR(0, 122, __pyx_L1_error)
 123:             "Misaligned shapes in grouped_masked_is_maximal:"
+124:             "data={}, groupby={}, mask={}".format(
    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Misaligned_shapes_in_grouped_mas, __pyx_n_s_format); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 124, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
+125:                 (<object> data).shape, (<object> groupby).shape, (<object> mask).shape,
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_data), __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 125, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_4 = __pyx_memoryview_fromslice(__pyx_v_groupby, 2, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_5numpy_int64_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_5numpy_int64_t, 0);; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 125, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 125, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_t_4 = __pyx_memoryview_fromslice(__pyx_v_mask, 2, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_5numpy_uint8_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_5numpy_uint8_t, 0);; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 125, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_shape); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 125, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_8);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_t_4 = NULL;
    __pyx_t_9 = 0;
    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) {
      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
      if (likely(__pyx_t_4)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
        __Pyx_INCREF(__pyx_t_4);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_3, function);
        __pyx_t_9 = 1;
      }
    }
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_3)) {
      PyObject *__pyx_temp[4] = {__pyx_t_4, __pyx_t_1, __pyx_t_7, __pyx_t_8};
      __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_9, 3+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 124, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
      PyObject *__pyx_temp[4] = {__pyx_t_4, __pyx_t_1, __pyx_t_7, __pyx_t_8};
      __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_9, 3+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 124, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
    } else
    #endif
    {
      __pyx_t_10 = PyTuple_New(3+__pyx_t_9); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 124, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_10);
      if (__pyx_t_4) {
        __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_4); __pyx_t_4 = NULL;
      }
      __Pyx_GIVEREF(__pyx_t_1);
      PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_9, __pyx_t_1);
      __Pyx_GIVEREF(__pyx_t_7);
      PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_9, __pyx_t_7);
      __Pyx_GIVEREF(__pyx_t_8);
      PyTuple_SET_ITEM(__pyx_t_10, 2+__pyx_t_9, __pyx_t_8);
      __pyx_t_1 = 0;
      __pyx_t_7 = 0;
      __pyx_t_8 = 0;
      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_10, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 124, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
    }
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 126:             )
 127:         )
 128: 
 129:     cdef:
 130:         Py_ssize_t i
 131:         Py_ssize_t j
 132:         np.int64_t group
 133:         np.int64_t value
+134:         np.ndarray[np.uint8_t, ndim=2] out = np.zeros_like(mask)
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 134, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_zeros_like); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 134, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_10);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_mask, 2, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_5numpy_uint8_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_5numpy_uint8_t, 0);; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 134, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_8 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_10))) {
    __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_10);
    if (likely(__pyx_t_8)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
      __Pyx_INCREF(__pyx_t_8);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_10, function);
    }
  }
  __pyx_t_3 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_10, __pyx_t_8, __pyx_t_2) : __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_2);
  __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 134, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
  if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 134, __pyx_L1_error)
  __pyx_t_11 = ((PyArrayObject *)__pyx_t_3);
  {
    __Pyx_BufFmt_StackElem __pyx_stack[1];
    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_out.rcbuffer->pybuffer, (PyObject*)__pyx_t_11, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint8_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack) == -1)) {
      __pyx_v_out = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_out.rcbuffer->pybuffer.buf = NULL;
      __PYX_ERR(0, 134, __pyx_L1_error)
    } else {__pyx_pybuffernd_out.diminfo[0].strides = __pyx_pybuffernd_out.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_out.diminfo[0].shape = __pyx_pybuffernd_out.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_out.diminfo[1].strides = __pyx_pybuffernd_out.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_out.diminfo[1].shape = __pyx_pybuffernd_out.rcbuffer->pybuffer.shape[1];
    }
  }
  __pyx_t_11 = 0;
  __pyx_v_out = ((PyArrayObject *)__pyx_t_3);
  __pyx_t_3 = 0;
+135:         dict best_per_group = {}
  __pyx_t_3 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 135, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_v_best_per_group = ((PyObject*)__pyx_t_3);
  __pyx_t_3 = 0;
+136:         Py_ssize_t nrows = np.PyArray_DIMS(data)[0]
  __pyx_v_nrows = (PyArray_DIMS(((PyArrayObject *)__pyx_v_data))[0]);
+137:         Py_ssize_t ncols = np.PyArray_DIMS(data)[1]
  __pyx_v_ncols = (PyArray_DIMS(((PyArrayObject *)__pyx_v_data))[1]);
 138: 
+139:     for i in range(nrows):
  __pyx_t_12 = __pyx_v_nrows;
  __pyx_t_13 = __pyx_t_12;
  for (__pyx_t_14 = 0; __pyx_t_14 < __pyx_t_13; __pyx_t_14+=1) {
    __pyx_v_i = __pyx_t_14;
+140:         best_per_group.clear()
    __pyx_t_15 = __Pyx_PyDict_Clear(__pyx_v_best_per_group); if (unlikely(__pyx_t_15 == ((int)-1))) __PYX_ERR(0, 140, __pyx_L1_error)
+141:         for j in range(ncols):
    __pyx_t_16 = __pyx_v_ncols;
    __pyx_t_17 = __pyx_t_16;
    for (__pyx_t_18 = 0; __pyx_t_18 < __pyx_t_17; __pyx_t_18+=1) {
      __pyx_v_j = __pyx_t_18;
 142: 
 143:             # NOTE: Callers are responsible for masking out values that should
 144:             # be treated as null here.
+145:             if not mask[i, j]:
      __pyx_t_19 = __pyx_v_i;
      __pyx_t_20 = __pyx_v_j;
      __pyx_t_9 = -1;
      if (__pyx_t_19 < 0) {
        __pyx_t_19 += __pyx_v_mask.shape[0];
        if (unlikely(__pyx_t_19 < 0)) __pyx_t_9 = 0;
      } else if (unlikely(__pyx_t_19 >= __pyx_v_mask.shape[0])) __pyx_t_9 = 0;
      if (__pyx_t_20 < 0) {
        __pyx_t_20 += __pyx_v_mask.shape[1];
        if (unlikely(__pyx_t_20 < 0)) __pyx_t_9 = 1;
      } else if (unlikely(__pyx_t_20 >= __pyx_v_mask.shape[1])) __pyx_t_9 = 1;
      if (unlikely(__pyx_t_9 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_9);
        __PYX_ERR(0, 145, __pyx_L1_error)
      }
      __pyx_t_6 = ((!((*((__pyx_t_5numpy_uint8_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_uint8_t *) ( /* dim=0 */ (__pyx_v_mask.data + __pyx_t_19 * __pyx_v_mask.strides[0]) )) + __pyx_t_20)) ))) != 0)) != 0);
      if (__pyx_t_6) {
/* … */
      }
+146:                 continue
        goto __pyx_L6_continue;
 147: 
+148:             value = data[i, j]
      __pyx_t_20 = __pyx_v_i;
      __pyx_t_19 = __pyx_v_j;
      __pyx_t_9 = -1;
      if (__pyx_t_20 < 0) {
        __pyx_t_20 += __pyx_pybuffernd_data.diminfo[0].shape;
        if (unlikely(__pyx_t_20 < 0)) __pyx_t_9 = 0;
      } else if (unlikely(__pyx_t_20 >= __pyx_pybuffernd_data.diminfo[0].shape)) __pyx_t_9 = 0;
      if (__pyx_t_19 < 0) {
        __pyx_t_19 += __pyx_pybuffernd_data.diminfo[1].shape;
        if (unlikely(__pyx_t_19 < 0)) __pyx_t_9 = 1;
      } else if (unlikely(__pyx_t_19 >= __pyx_pybuffernd_data.diminfo[1].shape)) __pyx_t_9 = 1;
      if (unlikely(__pyx_t_9 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_9);
        __PYX_ERR(0, 148, __pyx_L1_error)
      }
      __pyx_v_value = (*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_data.rcbuffer->pybuffer.buf, __pyx_t_20, __pyx_pybuffernd_data.diminfo[0].strides, __pyx_t_19, __pyx_pybuffernd_data.diminfo[1].strides));
+149:             group = groupby[i, j]
      __pyx_t_19 = __pyx_v_i;
      __pyx_t_20 = __pyx_v_j;
      __pyx_t_9 = -1;
      if (__pyx_t_19 < 0) {
        __pyx_t_19 += __pyx_v_groupby.shape[0];
        if (unlikely(__pyx_t_19 < 0)) __pyx_t_9 = 0;
      } else if (unlikely(__pyx_t_19 >= __pyx_v_groupby.shape[0])) __pyx_t_9 = 0;
      if (__pyx_t_20 < 0) {
        __pyx_t_20 += __pyx_v_groupby.shape[1];
        if (unlikely(__pyx_t_20 < 0)) __pyx_t_9 = 1;
      } else if (unlikely(__pyx_t_20 >= __pyx_v_groupby.shape[1])) __pyx_t_9 = 1;
      if (unlikely(__pyx_t_9 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_9);
        __PYX_ERR(0, 149, __pyx_L1_error)
      }
      __pyx_v_group = (*((__pyx_t_5numpy_int64_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_groupby.data + __pyx_t_19 * __pyx_v_groupby.strides[0]) )) + __pyx_t_20)) )));
 150: 
+151:             if group not in best_per_group:
      __pyx_t_3 = __Pyx_PyInt_From_npy_int64(__pyx_v_group); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 151, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_6 = (__Pyx_PyDict_ContainsTF(__pyx_t_3, __pyx_v_best_per_group, Py_NE)); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 151, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __pyx_t_5 = (__pyx_t_6 != 0);
      if (__pyx_t_5) {
/* … */
      }
+152:                 best_per_group[group] = j
        __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_j); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 152, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __pyx_t_10 = __Pyx_PyInt_From_npy_int64(__pyx_v_group); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 152, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_10);
        if (unlikely(PyDict_SetItem(__pyx_v_best_per_group, __pyx_t_10, __pyx_t_3) < 0)) __PYX_ERR(0, 152, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+153:                 continue
        goto __pyx_L6_continue;
 154: 
+155:             if value > data[i, best_per_group[group]]:
      __pyx_t_3 = __Pyx_PyInt_From_npy_int64(__pyx_v_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 155, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_10 = PyInt_FromSsize_t(__pyx_v_i); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 155, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_10);
      __pyx_t_2 = __Pyx_PyInt_From_npy_int64(__pyx_v_group); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 155, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_8 = __Pyx_PyDict_GetItem(__pyx_v_best_per_group, __pyx_t_2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 155, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 155, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_GIVEREF(__pyx_t_10);
      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_10);
      __Pyx_GIVEREF(__pyx_t_8);
      PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_8);
      __pyx_t_10 = 0;
      __pyx_t_8 = 0;
      __pyx_t_8 = __Pyx_PyObject_GetItem(((PyObject *)__pyx_v_data), __pyx_t_2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 155, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_2 = PyObject_RichCompare(__pyx_t_3, __pyx_t_8, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 155, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 155, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      if (__pyx_t_5) {
/* … */
      }
      __pyx_L6_continue:;
    }
+156:                 best_per_group[group] = j
        __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_j); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 156, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_8 = __Pyx_PyInt_From_npy_int64(__pyx_v_group); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 156, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_8);
        if (unlikely(PyDict_SetItem(__pyx_v_best_per_group, __pyx_t_8, __pyx_t_2) < 0)) __PYX_ERR(0, 156, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 157: 
+158:         for j in best_per_group.values():
    __pyx_t_16 = 0;
    __pyx_t_8 = __Pyx_dict_iterator(__pyx_v_best_per_group, 1, __pyx_n_s_values, (&__pyx_t_17), (&__pyx_t_9)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 158, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_8);
    __Pyx_XDECREF(__pyx_t_2);
    __pyx_t_2 = __pyx_t_8;
    __pyx_t_8 = 0;
    while (1) {
      __pyx_t_21 = __Pyx_dict_iter_next(__pyx_t_2, __pyx_t_17, &__pyx_t_16, NULL, &__pyx_t_8, NULL, __pyx_t_9);
      if (unlikely(__pyx_t_21 == 0)) break;
      if (unlikely(__pyx_t_21 == -1)) __PYX_ERR(0, 158, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __pyx_t_18 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_18 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 158, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      __pyx_v_j = __pyx_t_18;
+159:             out[i, j] = 1
      __pyx_t_20 = __pyx_v_i;
      __pyx_t_19 = __pyx_v_j;
      __pyx_t_21 = -1;
      if (__pyx_t_20 < 0) {
        __pyx_t_20 += __pyx_pybuffernd_out.diminfo[0].shape;
        if (unlikely(__pyx_t_20 < 0)) __pyx_t_21 = 0;
      } else if (unlikely(__pyx_t_20 >= __pyx_pybuffernd_out.diminfo[0].shape)) __pyx_t_21 = 0;
      if (__pyx_t_19 < 0) {
        __pyx_t_19 += __pyx_pybuffernd_out.diminfo[1].shape;
        if (unlikely(__pyx_t_19 < 0)) __pyx_t_21 = 1;
      } else if (unlikely(__pyx_t_19 >= __pyx_pybuffernd_out.diminfo[1].shape)) __pyx_t_21 = 1;
      if (unlikely(__pyx_t_21 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_21);
        __PYX_ERR(0, 159, __pyx_L1_error)
      }
      *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_uint8_t *, __pyx_pybuffernd_out.rcbuffer->pybuffer.buf, __pyx_t_20, __pyx_pybuffernd_out.diminfo[0].strides, __pyx_t_19, __pyx_pybuffernd_out.diminfo[1].strides) = 1;
    }
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  }
 160: 
+161:     return out.view(bool)
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_out), __pyx_n_s_view); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 161, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_8);
  __pyx_t_3 = NULL;
  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_8))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_8);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_8, function);
    }
  }
  __pyx_t_2 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_8, __pyx_t_3, ((PyObject *)__pyx_ptype_7cpython_4bool_bool)) : __Pyx_PyObject_CallOneArg(__pyx_t_8, ((PyObject *)__pyx_ptype_7cpython_4bool_bool));
  __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 161, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
  __pyx_r = __pyx_t_2;
  __pyx_t_2 = 0;
  goto __pyx_L0;