{"action":"closed","issue":{"url":"https://api.github.com/repos/pandas-dev/pandas/issues/19390","repository_url":"https://api.github.com/repos/pandas-dev/pandas","labels_url":"https://api.github.com/repos/pandas-dev/pandas/issues/19390/labels{/name}","comments_url":"https://api.github.com/repos/pandas-dev/pandas/issues/19390/comments","events_url":"https://api.github.com/repos/pandas-dev/pandas/issues/19390/events","html_url":"https://github.com/pandas-dev/pandas/issues/19390","id":291451469,"number":19390,"title":"Small differences in DataFrame/Panel ops","user":{"login":"jbrockmendel","id":8078968,"avatar_url":"https://avatars1.githubusercontent.com/u/8078968?v=4","gravatar_id":"","url":"https://api.github.com/users/jbrockmendel","html_url":"https://github.com/jbrockmendel","followers_url":"https://api.github.com/users/jbrockmendel/followers","following_url":"https://api.github.com/users/jbrockmendel/following{/other_user}","gists_url":"https://api.github.com/users/jbrockmendel/gists{/gist_id}","starred_url":"https://api.github.com/users/jbrockmendel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jbrockmendel/subscriptions","organizations_url":"https://api.github.com/users/jbrockmendel/orgs","repos_url":"https://api.github.com/users/jbrockmendel/repos","events_url":"https://api.github.com/users/jbrockmendel/events{/privacy}","received_events_url":"https://api.github.com/users/jbrockmendel/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-01-25T05:01:29Z","updated_at":"2018-02-04T08:00:04Z","closed_at":"2018-02-04T08:00:04Z","author_association":"CONTRIBUTOR","body":"https://github.com/pandas-dev/pandas/blob/master/pandas/core/ops.py#L959\r\n\r\n_flex_comp_method_FRAME and _comp_method_PANEL define `na_op` in a way that is _almost_ identical.  I'm wondering if the differences between them are intentional or if they can share an implementation.  The main difference after catching a `TypeError ` is a `isinstance(y, (np.ndarray, ABCSeries))` in the DataFrame version that only checks `isinstance(y, np.ndarray)` in the Panel version.  Is there a reason why Series is excluded in the Panel version?  (or why Index is excluded in either?)\r\n\r\n```\r\ndef _flex_comp_method_FRAME(op, name, str_rep=None, default_axis='columns',\r\n                            masker=False):\r\n    def na_op(x, y):\r\n       [...]\r\n        except TypeError:\r\n            xrav = x.ravel()\r\n            result = np.empty(x.size, dtype=bool)\r\n            if isinstance(y, (np.ndarray, ABCSeries)):\r\n                yrav = y.ravel()\r\n                mask = notna(xrav) & notna(yrav)\r\n                result[mask] = op(np.array(list(xrav[mask])),\r\n                                  np.array(list(yrav[mask])))\r\n            else:\r\n                mask = notna(xrav)\r\n                result[mask] = op(np.array(list(xrav[mask])), y)\r\n\r\n            if op == operator.ne:  # pragma: no cover\r\n                np.putmask(result, ~mask, True)\r\n            else:\r\n                np.putmask(result, ~mask, False)\r\n            result = result.reshape(x.shape)\r\n\r\n        return result\r\n\r\n[...]\r\ndef _comp_method_PANEL(op, name, str_rep=None, masker=False):\r\n    def na_op(x, y):\r\n        [...]\r\n        except TypeError:\r\n            xrav = x.ravel()\r\n            result = np.empty(x.size, dtype=bool)\r\n            if isinstance(y, np.ndarray):\r\n                yrav = y.ravel()\r\n                mask = notna(xrav) & notna(yrav)\r\n                result[mask] = op(np.array(list(xrav[mask])),\r\n                                  np.array(list(yrav[mask])))\r\n            else:\r\n                mask = notna(xrav)\r\n                result[mask] = op(np.array(list(xrav[mask])), y)\r\n\r\n            if op == operator.ne:  # pragma: no cover\r\n                np.putmask(result, ~mask, True)\r\n            else:\r\n                np.putmask(result, ~mask, False)\r\n            result = result.reshape(x.shape)\r\n\r\n        return result\r\n```"}}
{"actor":{"display_login":"jbrockmendel"}}