fastremap 1.16.0__tar.gz → 1.17.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. fastremap-1.17.0/.github/workflows/lint.yml +35 -0
  2. {fastremap-1.16.0 → fastremap-1.17.0}/.github/workflows/test.yml +1 -1
  3. fastremap-1.17.0/.vscode/settings.json +4 -0
  4. {fastremap-1.16.0 → fastremap-1.17.0}/AUTHORS +1 -0
  5. {fastremap-1.16.0 → fastremap-1.17.0}/ChangeLog +18 -0
  6. fastremap-1.17.0/MANIFEST.in +3 -0
  7. {fastremap-1.16.0/fastremap.egg-info → fastremap-1.17.0}/PKG-INFO +5 -6
  8. {fastremap-1.16.0 → fastremap-1.17.0}/README.md +3 -2
  9. {fastremap-1.16.0 → fastremap-1.17.0}/automated_test.py +136 -60
  10. fastremap-1.17.0/fastremap/__init__.py +47 -0
  11. fastremap-1.17.0/fastremap/fastremap.pyi +493 -0
  12. {fastremap-1.16.0/src → fastremap-1.17.0/fastremap}/fastremap.pyx +82 -59
  13. fastremap-1.17.0/fastremap/py.typed +0 -0
  14. {fastremap-1.16.0 → fastremap-1.17.0/fastremap.egg-info}/PKG-INFO +5 -6
  15. {fastremap-1.16.0 → fastremap-1.17.0}/fastremap.egg-info/SOURCES.txt +11 -5
  16. fastremap-1.17.0/fastremap.egg-info/pbr.json +1 -0
  17. fastremap-1.17.0/mypy.allowlist +2 -0
  18. {fastremap-1.16.0 → fastremap-1.17.0}/requirements_dev.txt +2 -1
  19. {fastremap-1.16.0 → fastremap-1.17.0}/setup.cfg +1 -2
  20. {fastremap-1.16.0 → fastremap-1.17.0}/setup.py +4 -3
  21. fastremap-1.16.0/MANIFEST.in +0 -3
  22. fastremap-1.16.0/fastremap.egg-info/pbr.json +0 -1
  23. {fastremap-1.16.0 → fastremap-1.17.0}/.dockerignore +0 -0
  24. {fastremap-1.16.0 → fastremap-1.17.0}/.github/workflows/build_wheel.yml +0 -0
  25. {fastremap-1.16.0 → fastremap-1.17.0}/LICENSE +0 -0
  26. {fastremap-1.16.0 → fastremap-1.17.0}/build_linux.sh +0 -0
  27. {fastremap-1.16.0/src → fastremap-1.17.0/fastremap}/fastremap.pxd +0 -0
  28. {fastremap-1.16.0/src → fastremap-1.17.0/fastremap}/ipt.hpp +0 -0
  29. {fastremap-1.16.0/src → fastremap-1.17.0/fastremap}/ska_flat_hash_map.hpp +0 -0
  30. {fastremap-1.16.0 → fastremap-1.17.0}/fastremap.egg-info/dependency_links.txt +0 -0
  31. {fastremap-1.16.0 → fastremap-1.17.0}/fastremap.egg-info/not-zip-safe +0 -0
  32. {fastremap-1.16.0 → fastremap-1.17.0}/fastremap.egg-info/requires.txt +0 -0
  33. {fastremap-1.16.0 → fastremap-1.17.0}/fastremap.egg-info/top_level.txt +0 -0
  34. {fastremap-1.16.0 → fastremap-1.17.0}/manylinux1.Dockerfile +0 -0
  35. {fastremap-1.16.0 → fastremap-1.17.0}/manylinux2010.Dockerfile +0 -0
  36. {fastremap-1.16.0 → fastremap-1.17.0}/manylinux2014.Dockerfile +0 -0
  37. {fastremap-1.16.0 → fastremap-1.17.0}/pyproject.toml +0 -0
  38. {fastremap-1.16.0 → fastremap-1.17.0}/requirements.txt +0 -0
  39. {fastremap-1.16.0 → fastremap-1.17.0}/test.py +0 -0
  40. {fastremap-1.16.0 → fastremap-1.17.0}/tox.ini +0 -0
@@ -0,0 +1,35 @@
1
+ name: Lint
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ pull_request:
7
+ branches: [master]
8
+
9
+ jobs:
10
+ mypy:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Setup Python
14
+ uses: actions/setup-python@v4
15
+ with:
16
+ python-version: 3.9
17
+ architecture: x64
18
+
19
+ - name: Checkout
20
+ uses: actions/checkout@v3
21
+
22
+ - name: Install dependencies
23
+ run: pip install -r requirements.txt -r requirements_dev.txt
24
+
25
+ - name: Add mypy annotator
26
+ uses: pr-annotators/mypy-pr-annotator@v1.0.0
27
+
28
+ - name: Run mypy
29
+ run: mypy fastremap
30
+
31
+ - name: Compile
32
+ run: python setup.py develop
33
+
34
+ - name: Run stub tests
35
+ run: python -m mypy.stubtest fastremap --allowlist mypy.allowlist
@@ -15,7 +15,7 @@ jobs:
15
15
  strategy:
16
16
  matrix:
17
17
  os: [ubuntu-latest, macos-latest, windows-latest]
18
- python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
18
+ python-version: ["3.9", "3.10", "3.11", "3.12", "3.13.3"]
19
19
 
20
20
  steps:
21
21
  - name: Set up Python ${{ matrix.python-version }}
@@ -0,0 +1,4 @@
1
+ {
2
+ "editor.rulers": [80],
3
+ "python.analysis.typeCheckingMode": "strict"
4
+ }
@@ -1,4 +1,5 @@
1
1
  Andreas Schwab <schwab@linux-m68k.org>
2
+ Matthew Vine <32849887+MattTheCuber@users.noreply.github.com>
2
3
  Max <maxme1@users.noreply.github.com>
3
4
  William Silversmith <william.silvermsith@gmail.com>
4
5
  William Silversmith <william.silversmith@gmail.com>
@@ -1,6 +1,24 @@
1
1
  CHANGES
2
2
  =======
3
3
 
4
+ 1.17.0
5
+ ------
6
+
7
+ * Add typing support (#45)
8
+ * Add optional arguments to remap\_from\_array functions (#46)
9
+
10
+ 1.16.2
11
+ ------
12
+
13
+ * perf+fix: faster simple case return + fix inverse
14
+ * test: check for renumber misordering
15
+ * fix(unique): ensure output of unique\_via\_renumber is sorted
16
+
17
+ 1.16.1
18
+ ------
19
+
20
+ * fix: exclude floating point and column length != 2
21
+
4
22
  1.16.0
5
23
  ------
6
24
 
@@ -0,0 +1,3 @@
1
+ include fastremap/ipt.hpp
2
+ include fastremap/ska_flat_hash_map.hpp
3
+ include LICENSE
@@ -1,13 +1,12 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.2
2
2
  Name: fastremap
3
- Version: 1.16.0
3
+ Version: 1.17.0
4
4
  Summary: Remap, mask, renumber, unique, and in-place transposition of 3D labeled images. Point cloud too.
5
5
  Home-page: https://github.com/seung-lab/fastremap/
6
6
  Author: William Silversmith
7
7
  Author-email: ws9@princeton.edu
8
8
  Classifier: Intended Audience :: Developers
9
9
  Classifier: Development Status :: 5 - Production/Stable
10
- Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
11
10
  Classifier: Programming Language :: Python
12
11
  Classifier: Programming Language :: Python :: 3
13
12
  Classifier: Programming Language :: Python :: 3.7
@@ -27,7 +26,6 @@ Dynamic: classifier
27
26
  Dynamic: description
28
27
  Dynamic: description-content-type
29
28
  Dynamic: home-page
30
- Dynamic: license-file
31
29
  Dynamic: requires-dist
32
30
  Dynamic: requires-python
33
31
  Dynamic: summary
@@ -95,8 +93,9 @@ binaries = fastremap.tobytes(labels, (64,64,64), order="F")
95
93
  - **inverse_component_map**: Extract an int-to-list-of-ints dictionary mapping from an image containing groups of components to an image containing the components.
96
94
  - **remap_from_array:** Same as remap, but the map is an array where the key is the array index and the value is the value.
97
95
  - **remap_from_array_kv:** Same as remap, but the map consists of two equal sized arrays, the first containing keys, the second containing values.
98
- - **asfortranarray:** Perform an in-place matrix transposition for rectangular arrays if memory is contiguous, standard numpy otherwise.
99
- - **ascontiguousarray:** Perform an in-place matrix transposition for rectangular arrays if memory is contiguous, standard numpy algorithm otherwise.
96
+ - **transpose:** Perform an in-place matrix transposition for rectangular arrays if memory is contiguous, apply the stock `np.transpose` function otherwise.
97
+ - **asfortranarray:** Perform an in-place matrix transposition for rectangular arrays if memory is contiguous, apply the stock `np.asfortranarray` function otherwise.
98
+ - **ascontiguousarray:** Perform an in-place matrix transposition for rectangular arrays if memory is contiguous, apply the stock `np.ascontiguousarray` function otherwise.
100
99
  - **minmax:** Compute the min and max of an array in one pass.
101
100
  - **pixel_pairs:** Computes the number of adjacent matching memory locations in an image. A quick heuristic for understanding if the image statistics are roughly similar to a connectomics segmentation.
102
101
  - **foreground:** Count the number of non-zero voxels rapidly.
@@ -61,8 +61,9 @@ binaries = fastremap.tobytes(labels, (64,64,64), order="F")
61
61
  - **inverse_component_map**: Extract an int-to-list-of-ints dictionary mapping from an image containing groups of components to an image containing the components.
62
62
  - **remap_from_array:** Same as remap, but the map is an array where the key is the array index and the value is the value.
63
63
  - **remap_from_array_kv:** Same as remap, but the map consists of two equal sized arrays, the first containing keys, the second containing values.
64
- - **asfortranarray:** Perform an in-place matrix transposition for rectangular arrays if memory is contiguous, standard numpy otherwise.
65
- - **ascontiguousarray:** Perform an in-place matrix transposition for rectangular arrays if memory is contiguous, standard numpy algorithm otherwise.
64
+ - **transpose:** Perform an in-place matrix transposition for rectangular arrays if memory is contiguous, apply the stock `np.transpose` function otherwise.
65
+ - **asfortranarray:** Perform an in-place matrix transposition for rectangular arrays if memory is contiguous, apply the stock `np.asfortranarray` function otherwise.
66
+ - **ascontiguousarray:** Perform an in-place matrix transposition for rectangular arrays if memory is contiguous, apply the stock `np.ascontiguousarray` function otherwise.
66
67
  - **minmax:** Compute the min and max of an array in one pass.
67
68
  - **pixel_pairs:** Computes the number of adjacent matching memory locations in an image. A quick heuristic for understanding if the image statistics are roughly similar to a connectomics segmentation.
68
69
  - **foreground:** Count the number of non-zero voxels rapidly.
@@ -302,94 +302,94 @@ def test_ascontiguousarray(dtype, dim):
302
302
 
303
303
  @pytest.mark.parametrize("dtype", [ np.uint8, np.uint16, np.uint32, np.uint64 ])
304
304
  def test_fit_dtype_uint(dtype):
305
- assert fastremap.fit_dtype(dtype, 0) == np.uint8
306
- assert fastremap.fit_dtype(dtype, 255) == np.uint8
307
- assert fastremap.fit_dtype(dtype, 256) == np.uint16
308
- assert fastremap.fit_dtype(dtype, 10000) == np.uint16
309
- assert fastremap.fit_dtype(dtype, 2**16 - 1) == np.uint16
310
- assert fastremap.fit_dtype(dtype, 2**16) == np.uint32
311
- assert fastremap.fit_dtype(dtype, 2**32) == np.uint64
312
- assert fastremap.fit_dtype(dtype, 2**64 - 1) == np.uint64
305
+ assert fastremap.fastremap._fit_dtype(dtype, 0) == np.uint8
306
+ assert fastremap.fastremap._fit_dtype(dtype, 255) == np.uint8
307
+ assert fastremap.fastremap._fit_dtype(dtype, 256) == np.uint16
308
+ assert fastremap.fastremap._fit_dtype(dtype, 10000) == np.uint16
309
+ assert fastremap.fastremap._fit_dtype(dtype, 2**16 - 1) == np.uint16
310
+ assert fastremap.fastremap._fit_dtype(dtype, 2**16) == np.uint32
311
+ assert fastremap.fastremap._fit_dtype(dtype, 2**32) == np.uint64
312
+ assert fastremap.fastremap._fit_dtype(dtype, 2**64 - 1) == np.uint64
313
313
 
314
314
  try:
315
- fastremap.fit_dtype(dtype, -1)
315
+ fastremap.fastremap._fit_dtype(dtype, -1)
316
316
  assert False
317
317
  except ValueError:
318
318
  pass
319
319
 
320
320
  try:
321
- fastremap.fit_dtype(dtype, 2**64)
321
+ fastremap.fastremap._fit_dtype(dtype, 2**64)
322
322
  except ValueError:
323
323
  pass
324
324
 
325
325
  @pytest.mark.parametrize("dtype", [ np.int8, np.int16, np.int32, np.int64 ])
326
326
  def test_fit_dtype_int(dtype):
327
- assert fastremap.fit_dtype(dtype, 0) == np.int8
328
- assert fastremap.fit_dtype(dtype, 127) == np.int8
329
- assert fastremap.fit_dtype(dtype, -128) == np.int8
330
- assert fastremap.fit_dtype(dtype, 128) == np.int16
331
- assert fastremap.fit_dtype(dtype, 10000) == np.int16
332
- assert fastremap.fit_dtype(dtype, 2**15 - 1) == np.int16
333
- assert fastremap.fit_dtype(dtype, 2**15) == np.int32
334
- assert fastremap.fit_dtype(dtype, 2**32) == np.int64
335
- assert fastremap.fit_dtype(dtype, 2**63 - 1) == np.int64
327
+ assert fastremap.fastremap._fit_dtype(dtype, 0) == np.int8
328
+ assert fastremap.fastremap._fit_dtype(dtype, 127) == np.int8
329
+ assert fastremap.fastremap._fit_dtype(dtype, -128) == np.int8
330
+ assert fastremap.fastremap._fit_dtype(dtype, 128) == np.int16
331
+ assert fastremap.fastremap._fit_dtype(dtype, 10000) == np.int16
332
+ assert fastremap.fastremap._fit_dtype(dtype, 2**15 - 1) == np.int16
333
+ assert fastremap.fastremap._fit_dtype(dtype, 2**15) == np.int32
334
+ assert fastremap.fastremap._fit_dtype(dtype, 2**32) == np.int64
335
+ assert fastremap.fastremap._fit_dtype(dtype, 2**63 - 1) == np.int64
336
336
 
337
337
  try:
338
- fastremap.fit_dtype(dtype, 2**63)
338
+ fastremap.fastremap._fit_dtype(dtype, 2**63)
339
339
  except ValueError:
340
340
  pass
341
341
 
342
342
  try:
343
- fastremap.fit_dtype(dtype, -2**63)
343
+ fastremap.fastremap._fit_dtype(dtype, -2**63)
344
344
  except ValueError:
345
345
  pass
346
346
 
347
347
  @pytest.mark.parametrize("dtype", [ np.float16, np.float32, np.float64 ])
348
348
  def test_fit_dtype_float(dtype):
349
- assert fastremap.fit_dtype(dtype, 0) == np.float32
350
- assert fastremap.fit_dtype(dtype, 127) == np.float32
351
- assert fastremap.fit_dtype(dtype, 128) == np.float32
352
- assert fastremap.fit_dtype(dtype, 10000) == np.float32
353
- assert fastremap.fit_dtype(dtype, 2**15 - 1) == np.float32
354
- assert fastremap.fit_dtype(dtype, 2**15) == np.float32
355
- assert fastremap.fit_dtype(dtype, 2**32) == np.float32
356
- assert fastremap.fit_dtype(dtype, 2**63 - 1) == np.float32
357
- assert fastremap.fit_dtype(dtype, -2**63) == np.float32
358
- assert fastremap.fit_dtype(dtype, 2**128) == np.float64
359
-
360
- assert fastremap.fit_dtype(dtype, 0, exotics=True) == np.float16
361
- assert fastremap.fit_dtype(dtype, 127, exotics=True) == np.float16
362
- assert fastremap.fit_dtype(dtype, 128, exotics=True) == np.float16
363
- assert fastremap.fit_dtype(dtype, 10000, exotics=True) == np.float16
364
- assert fastremap.fit_dtype(dtype, 2**15 - 1, exotics=True) == np.float16
365
- assert fastremap.fit_dtype(dtype, 2**15, exotics=True) == np.float16
366
- assert fastremap.fit_dtype(dtype, 2**32, exotics=True) == np.float32
367
- assert fastremap.fit_dtype(dtype, 2**63 - 1, exotics=True) == np.float32
368
- assert fastremap.fit_dtype(dtype, -2**63, exotics=True) == np.float32
349
+ assert fastremap.fastremap._fit_dtype(dtype, 0) == np.float32
350
+ assert fastremap.fastremap._fit_dtype(dtype, 127) == np.float32
351
+ assert fastremap.fastremap._fit_dtype(dtype, 128) == np.float32
352
+ assert fastremap.fastremap._fit_dtype(dtype, 10000) == np.float32
353
+ assert fastremap.fastremap._fit_dtype(dtype, 2**15 - 1) == np.float32
354
+ assert fastremap.fastremap._fit_dtype(dtype, 2**15) == np.float32
355
+ assert fastremap.fastremap._fit_dtype(dtype, 2**32) == np.float32
356
+ assert fastremap.fastremap._fit_dtype(dtype, 2**63 - 1) == np.float32
357
+ assert fastremap.fastremap._fit_dtype(dtype, -2**63) == np.float32
358
+ assert fastremap.fastremap._fit_dtype(dtype, 2**128) == np.float64
359
+
360
+ assert fastremap.fastremap._fit_dtype(dtype, 0, exotics=True) == np.float16
361
+ assert fastremap.fastremap._fit_dtype(dtype, 127, exotics=True) == np.float16
362
+ assert fastremap.fastremap._fit_dtype(dtype, 128, exotics=True) == np.float16
363
+ assert fastremap.fastremap._fit_dtype(dtype, 10000, exotics=True) == np.float16
364
+ assert fastremap.fastremap._fit_dtype(dtype, 2**15 - 1, exotics=True) == np.float16
365
+ assert fastremap.fastremap._fit_dtype(dtype, 2**15, exotics=True) == np.float16
366
+ assert fastremap.fastremap._fit_dtype(dtype, 2**32, exotics=True) == np.float32
367
+ assert fastremap.fastremap._fit_dtype(dtype, 2**63 - 1, exotics=True) == np.float32
368
+ assert fastremap.fastremap._fit_dtype(dtype, -2**63, exotics=True) == np.float32
369
369
 
370
370
  @pytest.mark.parametrize("dtype", [ np.csingle, np.cdouble ])
371
371
  @pytest.mark.parametrize("sign", [ 1, -1, 1j, -1j ])
372
372
  def test_fit_dtype_float(dtype, sign):
373
- assert fastremap.fit_dtype(dtype, sign * 0+0j) == np.csingle
374
- assert fastremap.fit_dtype(dtype, sign * 127) == np.csingle
375
- assert fastremap.fit_dtype(dtype, sign * 127) == np.csingle
376
- assert fastremap.fit_dtype(dtype, sign * 128) == np.csingle
377
- assert fastremap.fit_dtype(dtype, sign * 128) == np.csingle
378
- assert fastremap.fit_dtype(dtype, sign * 10000) == np.csingle
379
- assert fastremap.fit_dtype(dtype, sign * 10000) == np.csingle
380
- assert fastremap.fit_dtype(dtype, sign * 2**15 - 1) == np.csingle
381
- assert fastremap.fit_dtype(dtype, sign * 2**15) == np.csingle
382
- assert fastremap.fit_dtype(dtype, sign * 2**32) == np.csingle
383
- assert fastremap.fit_dtype(dtype, sign * 2**63 - 1) == np.csingle
384
- assert fastremap.fit_dtype(dtype, -2**63) == np.csingle
373
+ assert fastremap.fastremap._fit_dtype(dtype, sign * 0+0j) == np.csingle
374
+ assert fastremap.fastremap._fit_dtype(dtype, sign * 127) == np.csingle
375
+ assert fastremap.fastremap._fit_dtype(dtype, sign * 127) == np.csingle
376
+ assert fastremap.fastremap._fit_dtype(dtype, sign * 128) == np.csingle
377
+ assert fastremap.fastremap._fit_dtype(dtype, sign * 128) == np.csingle
378
+ assert fastremap.fastremap._fit_dtype(dtype, sign * 10000) == np.csingle
379
+ assert fastremap.fastremap._fit_dtype(dtype, sign * 10000) == np.csingle
380
+ assert fastremap.fastremap._fit_dtype(dtype, sign * 2**15 - 1) == np.csingle
381
+ assert fastremap.fastremap._fit_dtype(dtype, sign * 2**15) == np.csingle
382
+ assert fastremap.fastremap._fit_dtype(dtype, sign * 2**32) == np.csingle
383
+ assert fastremap.fastremap._fit_dtype(dtype, sign * 2**63 - 1) == np.csingle
384
+ assert fastremap.fastremap._fit_dtype(dtype, -2**63) == np.csingle
385
385
 
386
386
  try:
387
- fastremap.fit_dtype(dtype, sign * 2**128)
387
+ fastremap.fastremap._fit_dtype(dtype, sign * 2**128)
388
388
  assert False
389
389
  except ValueError:
390
390
  pass
391
391
 
392
- assert fastremap.fit_dtype(dtype, sign * 2**128, exotics=True) == np.cdouble
392
+ assert fastremap.fastremap._fit_dtype(dtype, sign * 2**128, exotics=True) == np.cdouble
393
393
 
394
394
  def test_minmax():
395
395
  volume = np.random.randint(-500, 500, size=(128,128,128))
@@ -440,7 +440,7 @@ def test_unique(order):
440
440
 
441
441
  labels = reorder(np.random.randint(0, 500, size=(128,128,128)))
442
442
  uniq_np, idx_np, inv_np, cts_np = np.unique(labels, return_counts=True, return_index=True, return_inverse=True)
443
- uniq_fr, idx_fr, cts_fr, inv_fr = fastremap.unique_via_array(labels.flatten(), np.max(labels), return_index=True, return_inverse=True)
443
+ uniq_fr, idx_fr, cts_fr, inv_fr = fastremap.fastremap._unique_via_array(labels.flatten(), np.max(labels), return_index=True, return_inverse=True)
444
444
  assert np.all(uniq_np == uniq_fr)
445
445
  assert np.all(inv_np.flatten() == inv_fr)
446
446
  assert np.all(cts_np == cts_fr)
@@ -457,7 +457,7 @@ def test_unique(order):
457
457
 
458
458
  labels = reorder(np.random.randint(-500, 500, size=(128,128,128)))
459
459
  uniq_np, idx_np, inv_np, cts_np = np.unique(labels, return_counts=True, return_index=True, return_inverse=True)
460
- uniq_fr, idx_fr, cts_fr, inv_fr = fastremap.unique_via_shifted_array(labels.flatten(), return_index=True, return_inverse=True)
460
+ uniq_fr, idx_fr, cts_fr, inv_fr = fastremap.fastremap._unique_via_shifted_array(labels.flatten(), return_index=True, return_inverse=True)
461
461
  assert np.all(uniq_np == uniq_fr)
462
462
  assert np.all(inv_np.flatten() == inv_fr)
463
463
  assert np.all(cts_np == cts_fr)
@@ -475,7 +475,7 @@ def test_unique(order):
475
475
  # array_unique + shift
476
476
  labels = reorder(np.random.randint(128**3 - 500, 128**3 + 500, size=(128,128,128)))
477
477
  uniq_np, idx_np, inv_np, cts_np = np.unique(labels, return_counts=True, return_index=True, return_inverse=True)
478
- uniq_fr, idx_fr, cts_fr, inv_fr = fastremap.unique_via_shifted_array(labels.flatten(), return_index=True, return_inverse=True)
478
+ uniq_fr, idx_fr, cts_fr, inv_fr = fastremap.fastremap._unique_via_shifted_array(labels.flatten(), return_index=True, return_inverse=True)
479
479
  assert np.all(uniq_np == uniq_fr)
480
480
  assert np.all(inv_np.flatten() == inv_fr)
481
481
  assert np.all(cts_np == cts_fr)
@@ -494,7 +494,7 @@ def test_unique(order):
494
494
  labels = reorder(np.random.randint(0, 1, size=(128,128,128)))
495
495
  labels[0,0,0] = 128**3 + 10
496
496
  uniq_np, idx_np, inv_np, cts_np = np.unique(labels, return_counts=True, return_index=True, return_inverse=True)
497
- uniq_fr, idx_fr, cts_fr, inv_fr = fastremap.unique_via_renumber(labels.flatten(), return_index=True, return_inverse=True)
497
+ uniq_fr, idx_fr, cts_fr, inv_fr = fastremap.fastremap._unique_via_renumber(labels.flatten(), return_index=True, return_inverse=True)
498
498
  assert np.all(uniq_np == uniq_fr)
499
499
  assert np.all(inv_np.flatten() == inv_fr)
500
500
  assert np.all(cts_np == cts_fr)
@@ -511,7 +511,7 @@ def test_unique(order):
511
511
 
512
512
  labels = reorder(np.random.randint(-1000, 128**3, size=(100,100,100)))
513
513
  uniq_np, cts_np = np.unique(labels, return_counts=True)
514
- uniq_fr, cts_fr = fastremap.unique_via_sort(labels.flatten())
514
+ uniq_fr, cts_fr = fastremap.fastremap._unique_via_sort(labels.flatten())
515
515
  assert np.all(uniq_np == uniq_fr)
516
516
  assert np.all(cts_np == cts_fr)
517
517
 
@@ -684,4 +684,80 @@ def test_widen_dtype():
684
684
  assert fastremap.widen_dtype(np.complex128, exotics=True) == np.clongdouble
685
685
  assert fastremap.widen_dtype(np.clongdouble, exotics=True) == np.clongdouble
686
686
 
687
+ def test_unique_order():
688
+ data = np.array([
689
+ 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704,
690
+ 1704, 1704, 1704, 1704, 1704, 1704, 106, 106, 106, 106, 106,
691
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
692
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
693
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
694
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
695
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
696
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
697
+ 106, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704,
698
+ 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704,
699
+ 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704,
700
+ 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704,
701
+ 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704,
702
+ 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704,
703
+ 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704,
704
+ 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704,
705
+ 1704, 1704, 1704, 1704, 1704, 106, 106, 106, 106, 106, 106,
706
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
707
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
708
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
709
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
710
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
711
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
712
+ 106, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704,
713
+ 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704,
714
+ 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704,
715
+ 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704,
716
+ 1704, 1704, 1704, 106, 106, 106, 106, 106, 106, 106, 106,
717
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
718
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
719
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
720
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
721
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
722
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
723
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
724
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
725
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
726
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
727
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
728
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
729
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
730
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
731
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
732
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
733
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
734
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
735
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
736
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
737
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
738
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
739
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
740
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
741
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
742
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
743
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
744
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
745
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
746
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
747
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
748
+ 106, 106, 106, 106, 106, 106, 106, 1873, 106, 106, 106,
749
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
750
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
751
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
752
+ 106, 106, 106, 106, 1873, 1873, 106, 106, 106, 106, 106,
753
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
754
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
755
+ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
756
+ 106, 1873, 1873, 106, 106, 106, 106, 106, 106, 106, 106,
757
+ 106, 106, 106, 106, 106, 106, 106
758
+ ])
759
+ tup = fastremap.unique(data, return_counts=True, return_index=True, return_inverse=True)
760
+ tup2 = np.unique(data, return_counts=True, return_index=True, return_inverse=True)
687
761
 
762
+ for res, ans in zip(tup, tup2):
763
+ assert np.all(res == ans)
@@ -0,0 +1,47 @@
1
+ from .fastremap import (
2
+ ascontiguousarray,
3
+ asfortranarray,
4
+ component_map,
5
+ foreground,
6
+ indices,
7
+ inverse_component_map,
8
+ mask,
9
+ mask_except,
10
+ minmax,
11
+ narrow_dtype,
12
+ pixel_pairs,
13
+ point_cloud,
14
+ refit,
15
+ remap,
16
+ remap_from_array,
17
+ remap_from_array_kv,
18
+ renumber,
19
+ tobytes,
20
+ transpose,
21
+ unique,
22
+ widen_dtype,
23
+ )
24
+
25
+ __all__ = [
26
+ "ascontiguousarray",
27
+ "asfortranarray",
28
+ "component_map",
29
+ "foreground",
30
+ "indices",
31
+ "inverse_component_map",
32
+ "mask",
33
+ "mask_except",
34
+ "minmax",
35
+ "narrow_dtype",
36
+ "pixel_pairs",
37
+ "point_cloud",
38
+ "refit",
39
+ "remap",
40
+ "remap_from_array",
41
+ "remap_from_array_kv",
42
+ "renumber",
43
+ "tobytes",
44
+ "transpose",
45
+ "unique",
46
+ "widen_dtype",
47
+ ]