Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added permutations_array to Moran_Local class #345

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions esda/crand.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ def crand(
w,
observed,
permutations,
permutations_array,
keep,
n_jobs,
stat_func,
Expand All @@ -91,6 +92,8 @@ def crand(
(N,) array with observed values
permutations : int
Number of permutations for conditional randomisation
permutations_array : ndarray
(permutations, ) array with indices of permuted
keep : Boolean
If True, store simulation; else do not return randomised statistics
n_jobs : int
Expand Down Expand Up @@ -170,8 +173,21 @@ def crand(
# self neighbor, since conditional randomization conditions on site i.
cardinalities = np.array((adj_matrix != 0).sum(1)).flatten()
max_card = cardinalities.max()
permuted_ids = vec_permutations(max_card, n, permutations, seed)


if permutations_array is None:
# Random permutation array
permuted_ids = vec_permutations(max_card, n, permutations, seed)
else:
# User defined permutation array
permuted_ids = permutations_array
if permuted_ids.shape[0] != permutations:
permutations = permuted_ids.shape[0]
warnings.warn(
f"Number of permutations has been adjusted to match the length of the "
f"permutations array. New value of 'permutations' is {permutations}.",
stacklevel=2,
)

if n_jobs != 1:
try:
import joblib # noqa: F401
Expand Down
1 change: 1 addition & 0 deletions esda/join_counts_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ def fit(self, y, n_jobs=1, permutations=999):
w=self.w,
observed=self.LJC,
permutations=permutations,
permutations_array=None,
keep=keep_simulations,
n_jobs=n_jobs,
stat_func=_ljc_uni,
Expand Down
6 changes: 6 additions & 0 deletions esda/moran.py
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,8 @@ class Moran_Local: # noqa: N801
permutations : int
number of random permutations for calculation of pseudo
p_values
permutations_array: array
user specified permutations
geoda_quads : boolean
(default=False)
If True use GeoDa scheme: HH=1, LL=2, LH=3, HL=4
Expand Down Expand Up @@ -1027,6 +1029,7 @@ def __init__(
w,
transformation="r",
permutations=PERMUTATIONS,
permutations_array=None,
geoda_quads=False,
n_jobs=1,
keep_simulations=True,
Expand Down Expand Up @@ -1064,6 +1067,7 @@ def __init__(
w,
self.Is,
permutations,
permutations_array,
keep_simulations,
n_jobs=n_jobs,
stat_func=_moran_local_crand,
Expand Down Expand Up @@ -1406,6 +1410,7 @@ def __init__(
w,
self.Is,
permutations,
None,
keep_simulations,
n_jobs=n_jobs,
stat_func=_moran_local_bv_crand,
Expand Down Expand Up @@ -1650,6 +1655,7 @@ def __init__(
w,
transformation=transformation,
permutations=permutations,
permutations_array=None,
geoda_quads=geoda_quads,
n_jobs=n_jobs,
keep_simulations=keep_simulations,
Expand Down
25 changes: 25 additions & 0 deletions esda/tests/test_moran.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ def setup_method(self):
f = libpysal.io.open(libpysal.examples.get_path("desmith.txt"))
self.y = np.array(f.by_col["z"])


@parametrize_desmith
def test_Moran_Local(self, w):
lm = moran.Moran_Local(
Expand All @@ -174,6 +175,30 @@ def test_Moran_Local(self, w):
)
np.testing.assert_allclose(lm.z_sim[0], -0.6990291160835514)
np.testing.assert_allclose(lm.p_z_sim[0], 0.24226691753791396)

@parametrize_desmith
def test_Moran_Local_custom_perms(self, w):
np.random.seed(SEED)
cardinalities = np.array((w.sparse != 0).sum(1)).flatten()
max_card = cardinalities.max()
original_array = np.arange(len(self.y))
permutations_array = np.zeros((99, max_card), dtype=np.int32)

for i in range(99):
random_number = np.random.randint(0, len(self.y) - max_card)
permutations_array[i] = original_array[random_number:random_number + max_card]

lm = moran.Moran_Local(
self.y,
w,
transformation="r",
permutations=99,
permutations_array=permutations_array,
keep_simulations=True,
seed=SEED,
)
np.testing.assert_allclose(lm.z_sim[0], -0.49229215590070813)
np.testing.assert_allclose(lm.p_z_sim[0], 0.311256412279757)

@parametrize_sac
def test_Moran_Local_labels(self, w):
Expand Down
Loading