{ "cells": [ { "cell_type": "markdown", "id": "aae4bcad-de91-4b2d-88c7-4aa5a87322cd", "metadata": {}, "source": [ "# Categorical Spatial Lags" ] }, { "cell_type": "code", "execution_count": null, "id": "0e80fbeb-d8f9-4d33-903d-ae9c8c0ca54b", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "\n", "from libpysal.graph import Graph\n", "from libpysal.graph._spatial_lag import _lag_spatial\n", "from libpysal.weights.util import lat2W\n", "\n", "graph = Graph.from_W(lat2W(3, 3))" ] }, { "cell_type": "code", "execution_count": 36, "id": "61a1c34b-3ede-4ff9-b4b4-f2f8ea63892e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 4., 6., 6., 10., 16., 14., 10., 18., 12.])" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = np.arange(9)\n", "_lag_spatial(graph, y)" ] }, { "cell_type": "code", "execution_count": null, "id": "229bacbc-d286-4cf8-9cd2-0ac370dc60e4", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(['b', 'a', 'b', 'c', 'b', 'c', 'b', 'c', 'b'], dtype=object)" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = np.array([*\"ababcbcbc\"])\n", "_lag_spatial(graph, y, categorical=True)" ] }, { "cell_type": "code", "execution_count": 28, "id": "e4b99d6e-1cea-450d-8a56-7f113f50e725", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(['a', 'b', 'a', 'a', 'c', 'b', 'c', 'b', 'c'], dtype=' 1\u001b[0m \u001b[43m_lag_spatial\u001b[49m\u001b[43m(\u001b[49m\u001b[43mgraph\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43my\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcategorical\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\n", "File \u001b[0;32m~/para/1_projects/code-pysal-libpysal/libpysal/libpysal/graph/_spatial_lag.py:58\u001b[0m, in \u001b[0;36m_lag_spatial\u001b[0;34m(graph, y, categorical, ties)\u001b[0m\n\u001b[1;32m 56\u001b[0m n_ties \u001b[38;5;241m=\u001b[39m gb\u001b[38;5;241m.\u001b[39mapply(_check_ties)\u001b[38;5;241m.\u001b[39msum()\n\u001b[1;32m 57\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m n_ties \u001b[38;5;129;01mand\u001b[39;00m ties \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mraise\u001b[39m\u001b[38;5;124m'\u001b[39m:\n\u001b[0;32m---> 58\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m 59\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mThere are \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mn_ties\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m ties that must be broken \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 60\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mto define the categorical \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 61\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mspatial lag for these observations. To address this \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 62\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124missue, consider setting `ties=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtryself\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m` \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 63\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mor `ties=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrandom\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m` or consult the documentation \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 64\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mabout ties and the categorical spatial lag.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 65\u001b[0m )\n\u001b[1;32m 66\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m ties \u001b[38;5;129;01min\u001b[39;00m (\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrandom\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtryself\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mraise\u001b[39m\u001b[38;5;124m'\u001b[39m):\n\u001b[1;32m 67\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m gb\u001b[38;5;241m.\u001b[39mapply(_get_categorical_lag)\u001b[38;5;241m.\u001b[39mvalues\n", "\u001b[0;31mValueError\u001b[0m: There are 2 ties that must be broken to define the categorical spatial lag for these observations. To address this issue, consider setting `ties='tryself'` or `ties='random'` or consult the documentation about ties and the categorical spatial lag." ] } ], "source": [ "_lag_spatial(graph, y, categorical=True)" ] }, { "cell_type": "code", "execution_count": 1, "id": "2e60d703-41f3-4dd8-80ad-c968e1e72e86", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy as np\n", "\n", "import libpysal\n", "\n", "np.random.seed(12345)\n", "w = libpysal.weights.lat2W(3, 3)\n", "y = np.array([*\"ababcbcbc\"])\n", "y_l = libpysal.weights.lag_categorical(w, y)\n", "np.array_equal(y_l, np.array([\"b\", \"a\", \"b\", \"c\", \"b\", \"c\", \"b\", \"c\", \"b\"]))" ] }, { "cell_type": "code", "execution_count": 2, "id": "cd0dcf01-ddfe-49a0-b6c5-da9a6d7d73cc", "metadata": {}, "outputs": [], "source": [ "from libpysal import graph" ] }, { "cell_type": "code", "execution_count": 3, "id": "86ffb3f3-4743-4339-acf7-36f42789093f", "metadata": {}, "outputs": [], "source": [ "g = graph.Graph.from_W(w)" ] }, { "cell_type": "code", "execution_count": 4, "id": "947f99bb-8b2f-44b0-810b-e1699559eaae", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "focal neighbor\n", "0 1 1.0\n", " 3 1.0\n", "1 0 1.0\n", " 2 1.0\n", " 4 1.0\n", "2 1 1.0\n", " 5 1.0\n", "3 0 1.0\n", " 4 1.0\n", " 6 1.0\n", "4 1 1.0\n", " 3 1.0\n", " 5 1.0\n", " 7 1.0\n", "5 2 1.0\n", " 4 1.0\n", " 8 1.0\n", "6 3 1.0\n", " 7 1.0\n", "7 4 1.0\n", " 6 1.0\n", " 8 1.0\n", "8 5 1.0\n", " 7 1.0\n", "Name: weight, dtype: float64" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g.adjacency" ] }, { "cell_type": "code", "execution_count": 5, "id": "f58b41ad-a1c1-49a5-ac06-1e50b2b7d66c", "metadata": {}, "outputs": [], "source": [ "from libpysal.graph._spatial_lag import _lag_spatial" ] }, { "cell_type": "code", "execution_count": 6, "id": "38db58fa-01ba-4243-9137-69cd4893732c", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(['b', 'a', 'b', 'c', 'b', 'c', 'b', 'c', 'b'], dtype=object)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy\n", "\n", "_lag_spatial(g, numpy.array(y), categorical=True)" ] }, { "cell_type": "markdown", "id": "afe32b9a-000b-4cb5-8e2d-7e708586e7e5", "metadata": {}, "source": [ "## No Ties" ] }, { "cell_type": "code", "execution_count": 7, "id": "5d075def-1b9c-4c19-b7fd-4d219fe5e754", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(['b', 'a', 'b', 'c', 'b', 'c', 'b', 'c', 'b'], dtype=object)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "_lag_spatial(g, numpy.array(y), categorical=True, ties=\"tryself\")" ] }, { "cell_type": "code", "execution_count": 8, "id": "b65e6f7e-081b-4d36-9e5a-edbe5fe12896", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.array_equal(y_l, _lag_spatial(g, numpy.array(y), categorical=True, ties=\"random\"))" ] }, { "cell_type": "code", "execution_count": 9, "id": "d3bb409f-7cd0-4258-b880-270461413340", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.array_equal(y_l, _lag_spatial(g, numpy.array(y), categorical=True, ties=\"raise\"))" ] }, { "cell_type": "markdown", "id": "e1c9b0f4-018f-44a8-9ed8-a6b7523d8108", "metadata": {}, "source": [ "## Ties" ] }, { "cell_type": "code", "execution_count": 10, "id": "de2f2e7b-a6f6-4e43-bf81-69facd3e0cff", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(['a', 'b', 'a', 'a', 'c', 'b', 'c', 'b', 'c'], dtype=' 2\u001b[0m np\u001b[38;5;241m.\u001b[39marray_equal(y_l, \u001b[43m_lag_spatial\u001b[49m\u001b[43m(\u001b[49m\u001b[43mg\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnumpy\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43marray\u001b[49m\u001b[43m(\u001b[49m\u001b[43my\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcategorical\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mties\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mraise\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m)\n", "File \u001b[0;32m~/para/1_projects/code-pysal-libpysal/libpysal/libpysal/graph/_spatial_lag.py:58\u001b[0m, in \u001b[0;36m_lag_spatial\u001b[0;34m(graph, y, categorical, ties)\u001b[0m\n\u001b[1;32m 56\u001b[0m n_ties \u001b[38;5;241m=\u001b[39m gb\u001b[38;5;241m.\u001b[39mapply(_check_ties)\u001b[38;5;241m.\u001b[39msum()\n\u001b[1;32m 57\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m n_ties \u001b[38;5;129;01mand\u001b[39;00m ties \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mraise\u001b[39m\u001b[38;5;124m'\u001b[39m:\n\u001b[0;32m---> 58\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m 59\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mThere are \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mn_ties\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m ties that must be broken \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 60\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mto define the categorical \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 61\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mspatial lag for these observations. To address this \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 62\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124missue, consider setting `ties=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtryself\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m` \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 63\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mor `ties=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrandom\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m` or consult the documentation \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 64\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mabout ties and the categorical spatial lag.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 65\u001b[0m )\n\u001b[1;32m 66\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m ties \u001b[38;5;129;01min\u001b[39;00m (\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrandom\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtryself\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mraise\u001b[39m\u001b[38;5;124m'\u001b[39m):\n\u001b[1;32m 67\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m gb\u001b[38;5;241m.\u001b[39mapply(_get_categorical_lag)\u001b[38;5;241m.\u001b[39mvalues\n", "\u001b[0;31mValueError\u001b[0m: There are 2 ties that must be broken to define the categorical spatial lag for these observations. To address this issue, consider setting `ties='tryself'` or `ties='random'` or consult the documentation about ties and the categorical spatial lag." ] } ], "source": [ "y_l = libpysal.weights.lag_categorical(w, y)\n", "np.array_equal(y_l, _lag_spatial(g, numpy.array(y), categorical=True, ties=\"raise\"))" ] }, { "cell_type": "code", "execution_count": null, "id": "e23094f6-94b7-49c1-a537-206ef4b89d37", "metadata": {}, "outputs": [], "source": [ "y_l" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.7" } }, "nbformat": 4, "nbformat_minor": 5 }