arraykit 0.6.3__tar.gz → 0.7.1__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.
- {arraykit-0.6.3/arraykit.egg-info → arraykit-0.7.1}/PKG-INFO +1 -1
- {arraykit-0.6.3 → arraykit-0.7.1}/README.rst +15 -0
- {arraykit-0.6.3 → arraykit-0.7.1/arraykit.egg-info}/PKG-INFO +1 -1
- {arraykit-0.6.3 → arraykit-0.7.1}/setup.py +1 -1
- {arraykit-0.6.3 → arraykit-0.7.1}/src/__init__.py +2 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/src/__init__.pyi +2 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/src/_arraykit.c +223 -1
- {arraykit-0.6.3 → arraykit-0.7.1}/test/test_util.py +127 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/LICENSE.txt +0 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/MANIFEST.in +0 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/arraykit.egg-info/SOURCES.txt +0 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/arraykit.egg-info/dependency_links.txt +0 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/arraykit.egg-info/requires.txt +0 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/arraykit.egg-info/top_level.txt +0 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/setup.cfg +0 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/src/py.typed +0 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/test/test_array_go.py +0 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/test/test_block_index.py +0 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/test/test_delimited_to_arrays.py +0 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/test/test_delimited_to_arrays_integration.py +0 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/test/test_delimited_to_arrays_property.py +0 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/test/test_nonzero_1d.py +0 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/test/test_nonzero_1d_property.py +0 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/test/test_pyi.py +0 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/test/test_split_after_count.py +0 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/test/test_tri_map.py +0 -0
- {arraykit-0.6.3 → arraykit-0.7.1}/test/test_type_discovery.py +0 -0
|
@@ -37,6 +37,21 @@ ArrayKit requires the following:
|
|
|
37
37
|
What is New in ArrayKit
|
|
38
38
|
-------------------------
|
|
39
39
|
|
|
40
|
+
|
|
41
|
+
0.7.1
|
|
42
|
+
............
|
|
43
|
+
|
|
44
|
+
Extended ``array_to_tuple_array()`` and ``array_to_tuple_iter()`` to support 1D arrays.
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
0.7.0
|
|
48
|
+
............
|
|
49
|
+
|
|
50
|
+
Added ``array_to_tuple_array()``.
|
|
51
|
+
|
|
52
|
+
Added ``array_to_tuple_iter()``.
|
|
53
|
+
|
|
54
|
+
|
|
40
55
|
0.6.3
|
|
41
56
|
............
|
|
42
57
|
|
|
@@ -5,7 +5,7 @@ from setuptools import Extension # type: ignore
|
|
|
5
5
|
from setuptools import setup
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
|
|
8
|
-
AK_VERSION = '0.
|
|
8
|
+
AK_VERSION = '0.7.1'
|
|
9
9
|
|
|
10
10
|
def get_long_description() -> str:
|
|
11
11
|
return '''The ArrayKit library provides utilities for creating and transforming NumPy arrays, implementing performance-critical StaticFrame operations as Python C extensions.
|
|
@@ -28,4 +28,6 @@ from ._arraykit import count_iteration as count_iteration
|
|
|
28
28
|
from ._arraykit import first_true_1d as first_true_1d
|
|
29
29
|
from ._arraykit import first_true_2d as first_true_2d
|
|
30
30
|
from ._arraykit import slice_to_ascending_slice as slice_to_ascending_slice
|
|
31
|
+
from ._arraykit import array_to_tuple_array as array_to_tuple_array
|
|
32
|
+
from ._arraykit import array_to_tuple_iter as array_to_tuple_iter
|
|
31
33
|
from ._arraykit import nonzero_1d as nonzero_1d
|
|
@@ -161,3 +161,5 @@ def first_true_1d(__array: np.ndarray, *, forward: bool) -> int: ...
|
|
|
161
161
|
def first_true_2d(__array: np.ndarray, *, forward: bool, axis: int) -> np.ndarray: ...
|
|
162
162
|
def nonzero_1d(__array: np.ndarray, /) -> np.ndarray: ...
|
|
163
163
|
def slice_to_ascending_slice(__slice: slice, __size: int) -> slice: ...
|
|
164
|
+
def array_to_tuple_array(__array: np.ndarray) -> np.ndarray: ...
|
|
165
|
+
def array_to_tuple_iter(__array: np.ndarray) -> tp.Iterator[tp.Tuple[tp.Any, ...]]: ...
|
|
@@ -37,6 +37,18 @@ const static size_t UCS4_SIZE = sizeof(Py_UCS4);
|
|
|
37
37
|
} \
|
|
38
38
|
} while (0)
|
|
39
39
|
|
|
40
|
+
// Given a PyObject, raise if not an array or is not two dimensional.
|
|
41
|
+
# define AK_CHECK_NUMPY_ARRAY_2D(O) \
|
|
42
|
+
do { \
|
|
43
|
+
AK_CHECK_NUMPY_ARRAY(O) \
|
|
44
|
+
int ndim = PyArray_NDIM((PyArrayObject *)O); \
|
|
45
|
+
if (ndim != 2) { \
|
|
46
|
+
return PyErr_Format(PyExc_NotImplementedError,\
|
|
47
|
+
"Expected a 2D array, not %i.", \
|
|
48
|
+
ndim); \
|
|
49
|
+
} \
|
|
50
|
+
} while (0)
|
|
51
|
+
|
|
40
52
|
// Placeholder of not implemented pathways / debugging.
|
|
41
53
|
# define AK_NOT_IMPLEMENTED(msg) \
|
|
42
54
|
do { \
|
|
@@ -3511,6 +3523,215 @@ array_deepcopy(PyObject *m, PyObject *args, PyObject *kwargs)
|
|
|
3511
3523
|
return AK_ArrayDeepCopy(m, (PyArrayObject*)array, memo);
|
|
3512
3524
|
}
|
|
3513
3525
|
|
|
3526
|
+
//------------------------------------------------------------------------------
|
|
3527
|
+
// Given a 1D or 2D array, return a 1D object array of tuples.
|
|
3528
|
+
static PyObject *
|
|
3529
|
+
array_to_tuple_array(PyObject *Py_UNUSED(m), PyObject *a)
|
|
3530
|
+
{
|
|
3531
|
+
AK_CHECK_NUMPY_ARRAY(a);
|
|
3532
|
+
PyArrayObject *input_array = (PyArrayObject *)a;
|
|
3533
|
+
int ndim = PyArray_NDIM(input_array);
|
|
3534
|
+
if (ndim != 1 && ndim != 2) {
|
|
3535
|
+
return PyErr_Format(PyExc_NotImplementedError,
|
|
3536
|
+
"Expected 1D or 2D array, not %i.",
|
|
3537
|
+
ndim);
|
|
3538
|
+
}
|
|
3539
|
+
|
|
3540
|
+
npy_intp num_rows = PyArray_DIM(input_array, 0);
|
|
3541
|
+
npy_intp dims[] = {num_rows};
|
|
3542
|
+
// NOTE: this initializes values to NULL, not None
|
|
3543
|
+
PyObject* output = PyArray_SimpleNew(1, dims, NPY_OBJECT);
|
|
3544
|
+
if (output == NULL) {
|
|
3545
|
+
return NULL;
|
|
3546
|
+
}
|
|
3547
|
+
|
|
3548
|
+
PyObject** output_data = (PyObject**)PyArray_DATA((PyArrayObject*)output);
|
|
3549
|
+
PyObject** p = output_data;
|
|
3550
|
+
PyObject** p_end = p + num_rows;
|
|
3551
|
+
npy_intp i = 0;
|
|
3552
|
+
PyObject* tuple;
|
|
3553
|
+
PyObject* item;
|
|
3554
|
+
|
|
3555
|
+
if (ndim == 2) {
|
|
3556
|
+
npy_intp num_cols = PyArray_DIM(input_array, 1);
|
|
3557
|
+
npy_intp j;
|
|
3558
|
+
while (p < p_end) {
|
|
3559
|
+
tuple = PyTuple_New(num_cols);
|
|
3560
|
+
if (tuple == NULL) {
|
|
3561
|
+
goto error;
|
|
3562
|
+
}
|
|
3563
|
+
for (j = 0; j < num_cols; ++j) {
|
|
3564
|
+
// cannot assume input_array is contiguous
|
|
3565
|
+
item = PyArray_ToScalar(PyArray_GETPTR2(input_array, i, j), input_array);
|
|
3566
|
+
if (item == NULL) {
|
|
3567
|
+
Py_DECREF(tuple);
|
|
3568
|
+
goto error;
|
|
3569
|
+
}
|
|
3570
|
+
PyTuple_SET_ITEM(tuple, j, item); // steals reference to item
|
|
3571
|
+
}
|
|
3572
|
+
*p++ = tuple; // assign with new ref, no incr needed
|
|
3573
|
+
i++;
|
|
3574
|
+
}
|
|
3575
|
+
}
|
|
3576
|
+
else { // ndim == 1
|
|
3577
|
+
while (p < p_end) {
|
|
3578
|
+
tuple = PyTuple_New(1);
|
|
3579
|
+
if (tuple == NULL) {
|
|
3580
|
+
goto error;
|
|
3581
|
+
}
|
|
3582
|
+
// scalar returned in is native PyObject from object arrays
|
|
3583
|
+
item = PyArray_ToScalar(PyArray_GETPTR1(input_array, i), input_array);
|
|
3584
|
+
if (item == NULL) {
|
|
3585
|
+
Py_DECREF(tuple);
|
|
3586
|
+
goto error;
|
|
3587
|
+
}
|
|
3588
|
+
PyTuple_SET_ITEM(tuple, 0, item); // steals reference to item
|
|
3589
|
+
*p++ = tuple; // assign with new ref, no incr needed
|
|
3590
|
+
i++;
|
|
3591
|
+
}
|
|
3592
|
+
}
|
|
3593
|
+
PyArray_CLEARFLAGS((PyArrayObject *)output, NPY_ARRAY_WRITEABLE);
|
|
3594
|
+
return output;
|
|
3595
|
+
error:
|
|
3596
|
+
p = output_data;
|
|
3597
|
+
p_end = p + num_rows;
|
|
3598
|
+
while (p < p_end) { // decref all tuples within array
|
|
3599
|
+
Py_XDECREF(*p++); // xdec as might be NULL
|
|
3600
|
+
}
|
|
3601
|
+
Py_DECREF(output);
|
|
3602
|
+
return NULL;
|
|
3603
|
+
}
|
|
3604
|
+
|
|
3605
|
+
//------------------------------------------------------------------------------
|
|
3606
|
+
// ArrayToTupleIterator
|
|
3607
|
+
|
|
3608
|
+
static PyTypeObject ATTType;
|
|
3609
|
+
|
|
3610
|
+
typedef struct ATTObject {
|
|
3611
|
+
PyObject_HEAD
|
|
3612
|
+
PyArrayObject* array;
|
|
3613
|
+
npy_intp num_rows;
|
|
3614
|
+
npy_intp num_cols;
|
|
3615
|
+
Py_ssize_t pos; // current index state, mutated in-place
|
|
3616
|
+
} ATTObject;
|
|
3617
|
+
|
|
3618
|
+
static PyObject *
|
|
3619
|
+
ATT_new(PyArrayObject* array,
|
|
3620
|
+
npy_intp num_rows,
|
|
3621
|
+
npy_intp num_cols) {
|
|
3622
|
+
ATTObject* a2dt = PyObject_New(ATTObject, &ATTType);
|
|
3623
|
+
if (!a2dt) {
|
|
3624
|
+
return NULL;
|
|
3625
|
+
}
|
|
3626
|
+
Py_INCREF((PyObject*)array);
|
|
3627
|
+
a2dt->array = array;
|
|
3628
|
+
a2dt->num_rows = num_rows;
|
|
3629
|
+
a2dt->num_cols = num_cols; // -1 for 1D array
|
|
3630
|
+
a2dt->pos = 0;
|
|
3631
|
+
return (PyObject *)a2dt;
|
|
3632
|
+
}
|
|
3633
|
+
|
|
3634
|
+
static void
|
|
3635
|
+
ATT_dealloc(ATTObject *self) {
|
|
3636
|
+
Py_DECREF((PyObject*)self->array);
|
|
3637
|
+
PyObject_Del((PyObject*)self);
|
|
3638
|
+
}
|
|
3639
|
+
|
|
3640
|
+
static PyObject*
|
|
3641
|
+
ATT_iter(ATTObject *self) {
|
|
3642
|
+
Py_INCREF(self);
|
|
3643
|
+
return (PyObject*)self;
|
|
3644
|
+
}
|
|
3645
|
+
|
|
3646
|
+
static PyObject *
|
|
3647
|
+
ATT_iternext(ATTObject *self) {
|
|
3648
|
+
Py_ssize_t i = self->pos;
|
|
3649
|
+
if (i < self->num_rows) {
|
|
3650
|
+
npy_intp num_cols = self->num_cols;
|
|
3651
|
+
PyArrayObject* array = self->array;
|
|
3652
|
+
PyObject* item;
|
|
3653
|
+
PyObject* tuple;
|
|
3654
|
+
|
|
3655
|
+
if (num_cols > -1) { // ndim == 2
|
|
3656
|
+
tuple = PyTuple_New(num_cols);
|
|
3657
|
+
if (tuple == NULL) {
|
|
3658
|
+
return NULL;
|
|
3659
|
+
}
|
|
3660
|
+
for (npy_intp j = 0; j < num_cols; ++j) {
|
|
3661
|
+
// cannot assume array is contiguous
|
|
3662
|
+
item = PyArray_ToScalar(PyArray_GETPTR2(array, i, j), array);
|
|
3663
|
+
if (item == NULL) {
|
|
3664
|
+
Py_DECREF(tuple);
|
|
3665
|
+
return NULL;
|
|
3666
|
+
}
|
|
3667
|
+
PyTuple_SET_ITEM(tuple, j, item); // steals reference to item
|
|
3668
|
+
}
|
|
3669
|
+
}
|
|
3670
|
+
else { // ndim == 1
|
|
3671
|
+
tuple = PyTuple_New(1);
|
|
3672
|
+
if (tuple == NULL) {
|
|
3673
|
+
return NULL;
|
|
3674
|
+
}
|
|
3675
|
+
item = PyArray_ToScalar(PyArray_GETPTR1(array, i), array);
|
|
3676
|
+
if (item == NULL) {
|
|
3677
|
+
Py_DECREF(tuple);
|
|
3678
|
+
return NULL;
|
|
3679
|
+
}
|
|
3680
|
+
PyTuple_SET_ITEM(tuple, 0, item); // steals reference to item
|
|
3681
|
+
}
|
|
3682
|
+
self->pos++;
|
|
3683
|
+
return tuple;
|
|
3684
|
+
}
|
|
3685
|
+
return NULL;
|
|
3686
|
+
}
|
|
3687
|
+
|
|
3688
|
+
// static PyObject *
|
|
3689
|
+
// ATT_reversed(ATTObject *self) {
|
|
3690
|
+
// return ATT_new(self->bi, !self->reversed);
|
|
3691
|
+
// }
|
|
3692
|
+
|
|
3693
|
+
static PyObject *
|
|
3694
|
+
ATT_length_hint(ATTObject *self) {
|
|
3695
|
+
Py_ssize_t len = Py_MAX(0, self->num_rows - self->pos);
|
|
3696
|
+
return PyLong_FromSsize_t(len);
|
|
3697
|
+
}
|
|
3698
|
+
|
|
3699
|
+
static PyMethodDef ATT_methods[] = {
|
|
3700
|
+
{"__length_hint__", (PyCFunction)ATT_length_hint, METH_NOARGS, NULL},
|
|
3701
|
+
// {"__reversed__", (PyCFunction)ATT_reversed, METH_NOARGS, NULL},
|
|
3702
|
+
{NULL},
|
|
3703
|
+
};
|
|
3704
|
+
|
|
3705
|
+
static PyTypeObject ATTType = {
|
|
3706
|
+
PyVarObject_HEAD_INIT(NULL, 0)
|
|
3707
|
+
.tp_basicsize = sizeof(ATTObject),
|
|
3708
|
+
.tp_dealloc = (destructor) ATT_dealloc,
|
|
3709
|
+
.tp_iter = (getiterfunc) ATT_iter,
|
|
3710
|
+
.tp_iternext = (iternextfunc) ATT_iternext,
|
|
3711
|
+
.tp_methods = ATT_methods,
|
|
3712
|
+
.tp_name = "arraykit.ATTIterator",
|
|
3713
|
+
};
|
|
3714
|
+
|
|
3715
|
+
// Given a 2D array, return an iterator of row tuples.
|
|
3716
|
+
static PyObject *
|
|
3717
|
+
array_to_tuple_iter(PyObject *Py_UNUSED(m), PyObject *a)
|
|
3718
|
+
{
|
|
3719
|
+
AK_CHECK_NUMPY_ARRAY(a);
|
|
3720
|
+
PyArrayObject *array = (PyArrayObject *)a;
|
|
3721
|
+
int ndim = PyArray_NDIM(array);
|
|
3722
|
+
if (ndim != 1 && ndim != 2) {
|
|
3723
|
+
return PyErr_Format(PyExc_NotImplementedError,
|
|
3724
|
+
"Expected 1D or 2D array, not %i.",
|
|
3725
|
+
ndim);
|
|
3726
|
+
}
|
|
3727
|
+
npy_intp num_rows = PyArray_DIM(array, 0);
|
|
3728
|
+
npy_intp num_cols = -1; // indicate 1d
|
|
3729
|
+
if (ndim == 2) {
|
|
3730
|
+
num_cols = PyArray_DIM(array, 1);
|
|
3731
|
+
}
|
|
3732
|
+
return ATT_new(array, num_rows, num_cols);
|
|
3733
|
+
}
|
|
3734
|
+
|
|
3514
3735
|
//------------------------------------------------------------------------------
|
|
3515
3736
|
// type resolution
|
|
3516
3737
|
|
|
@@ -5944,7 +6165,6 @@ TriMap_dealloc(TriMapObject *self) {
|
|
|
5944
6165
|
if (self->many_from != NULL) {
|
|
5945
6166
|
// decref all arrays before freeing
|
|
5946
6167
|
for (Py_ssize_t i = 0; i < self->many_count; i++) {
|
|
5947
|
-
// NOTE: using dot to get to pointer?
|
|
5948
6168
|
Py_DECREF((PyObject*)self->many_from[i].dst);
|
|
5949
6169
|
}
|
|
5950
6170
|
PyMem_Free(self->many_from);
|
|
@@ -7259,6 +7479,8 @@ static PyMethodDef arraykit_methods[] = {
|
|
|
7259
7479
|
(PyCFunction)array_deepcopy,
|
|
7260
7480
|
METH_VARARGS | METH_KEYWORDS,
|
|
7261
7481
|
NULL},
|
|
7482
|
+
{"array_to_tuple_array", array_to_tuple_array, METH_O, NULL},
|
|
7483
|
+
{"array_to_tuple_iter", array_to_tuple_iter, METH_O, NULL},
|
|
7262
7484
|
{"resolve_dtype", resolve_dtype, METH_VARARGS, NULL},
|
|
7263
7485
|
{"resolve_dtype_iter", resolve_dtype_iter, METH_O, NULL},
|
|
7264
7486
|
{"first_true_1d",
|
|
@@ -22,6 +22,8 @@ from arraykit import count_iteration
|
|
|
22
22
|
from arraykit import first_true_1d
|
|
23
23
|
from arraykit import first_true_2d
|
|
24
24
|
from arraykit import slice_to_ascending_slice
|
|
25
|
+
from arraykit import array_to_tuple_array
|
|
26
|
+
from arraykit import array_to_tuple_iter
|
|
25
27
|
|
|
26
28
|
from performance.reference.util import get_new_indexers_and_screen_ak as get_new_indexers_and_screen_full
|
|
27
29
|
from arraykit import get_new_indexers_and_screen
|
|
@@ -283,6 +285,131 @@ class TestUnit(unittest.TestCase):
|
|
|
283
285
|
with self.assertRaises(TypeError):
|
|
284
286
|
a2 = array_deepcopy(a1, ())
|
|
285
287
|
|
|
288
|
+
#---------------------------------------------------------------------------
|
|
289
|
+
def test_array2d_to_array1d_1d_a(self) -> None:
|
|
290
|
+
a1 = np.arange(10)
|
|
291
|
+
a2 = array_to_tuple_array(a1)
|
|
292
|
+
self.assertEqual(a2.tolist(), [(0,), (1,), (2,), (3,), (4,), (5,), (6,), (7,), (8,), (9,)])
|
|
293
|
+
|
|
294
|
+
def test_array2d_to_array1d_1d_b(self) -> None:
|
|
295
|
+
a1 = np.array(['aaa', 'b', 'ccc'])
|
|
296
|
+
a2 = array_to_tuple_array(a1)
|
|
297
|
+
self.assertEqual(a2.tolist(), [('aaa',), ('b',), ('ccc',)])
|
|
298
|
+
|
|
299
|
+
def test_array2d_to_array1d_1d_c(self) -> None:
|
|
300
|
+
a1 = np.array([None, 'b', 30])
|
|
301
|
+
a2 = array_to_tuple_array(a1)
|
|
302
|
+
self.assertEqual(a2.tolist(), [(None,), ('b',), (30,)])
|
|
303
|
+
|
|
304
|
+
def test_array2d_to_array1d_1d_d(self) -> None:
|
|
305
|
+
a1 = np.array([('a', 10), ('b', 30), ('c', 5)], dtype=object)
|
|
306
|
+
a2 = array_to_tuple_array(a1)
|
|
307
|
+
self.assertEqual(a2.tolist(), [('a', 10), ('b', 30), ('c', 5)])
|
|
308
|
+
|
|
309
|
+
def test_array2d_to_array1d_1d_e(self) -> None:
|
|
310
|
+
a1 = np.array([True, False, True], dtype=object)
|
|
311
|
+
a2 = array_to_tuple_array(a1)
|
|
312
|
+
self.assertIs(a2[0][0].__class__, bool)
|
|
313
|
+
self.assertEqual(a2.tolist(), [(True,), (False,), (True,)])
|
|
314
|
+
|
|
315
|
+
def test_array2d_to_array1d_b(self) -> None:
|
|
316
|
+
a1 = np.arange(10, dtype=np.int64).reshape(5, 2)
|
|
317
|
+
result = array_to_tuple_array(a1)
|
|
318
|
+
assert isinstance(result[0], tuple)
|
|
319
|
+
assert result[0] == (0, 1)
|
|
320
|
+
self.assertIs(type(result[0][0]), np.int64)
|
|
321
|
+
self.assertFalse(result.flags.writeable)
|
|
322
|
+
self.assertEqual(tuple(result), ((0, 1), (2, 3), (4, 5), (6, 7), (8, 9)))
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
def test_array2d_to_array1d_c(self) -> None:
|
|
326
|
+
a1 = np.array([["a", "b"], ["ccc", "ddd"], ["ee", "ff"]])
|
|
327
|
+
a2 = array_to_tuple_array(a1)
|
|
328
|
+
self.assertEqual(a2.tolist(), [('a', 'b'), ('ccc', 'ddd'), ('ee', 'ff')])
|
|
329
|
+
|
|
330
|
+
def test_array2d_to_array1d_d(self) -> None:
|
|
331
|
+
a1 = np.array([[3, 5], [10, 20], [7, 2]], dtype=np.uint8)
|
|
332
|
+
a2 = array_to_tuple_array(a1)
|
|
333
|
+
self.assertEqual(a2.tolist(), [(3, 5), (10, 20), (7, 2)])
|
|
334
|
+
self.assertIs(type(a2[0][0]), np.uint8)
|
|
335
|
+
|
|
336
|
+
def test_array2d_to_array1d_e(self) -> None:
|
|
337
|
+
a1 = np.arange(20, dtype=np.int64).reshape(4, 5)
|
|
338
|
+
result = array_to_tuple_array(a1)
|
|
339
|
+
self.assertEqual(result.tolist(), [(0, 1, 2, 3, 4), (5, 6, 7, 8, 9), (10, 11, 12, 13, 14), (15, 16, 17, 18, 19)])
|
|
340
|
+
|
|
341
|
+
#---------------------------------------------------------------------------
|
|
342
|
+
def test_array2d_tuple_iter_a(self) -> None:
|
|
343
|
+
a1 = np.arange(20, dtype=np.int64).reshape(4, 5)
|
|
344
|
+
result = list(array_to_tuple_iter(a1))
|
|
345
|
+
self.assertEqual(len(result), 4)
|
|
346
|
+
self.assertEqual(result, [(0, 1, 2, 3, 4), (5, 6, 7, 8, 9), (10, 11, 12, 13, 14), (15, 16, 17, 18, 19)])
|
|
347
|
+
|
|
348
|
+
def test_array2d_tuple_iter_b(self) -> None:
|
|
349
|
+
a1 = np.arange(20, dtype=np.int64).reshape(10, 2)
|
|
350
|
+
result = list(array_to_tuple_iter(a1))
|
|
351
|
+
self.assertEqual(result, [(0, 1), (2, 3), (4, 5), (6, 7), (8, 9), (10, 11), (12, 13), (14, 15), (16, 17), (18, 19)])
|
|
352
|
+
|
|
353
|
+
def test_array2d_tuple_iter_c(self) -> None:
|
|
354
|
+
a1 = np.array([['aaa', 'bb'], ['c', 'dd'], ['ee', 'fffff']])
|
|
355
|
+
it = array_to_tuple_iter(a1)
|
|
356
|
+
self.assertEqual(it.__length_hint__(), 3)
|
|
357
|
+
self.assertEqual(next(it), ('aaa', 'bb'))
|
|
358
|
+
self.assertEqual(it.__length_hint__(), 2)
|
|
359
|
+
self.assertEqual(next(it), ('c', 'dd'))
|
|
360
|
+
self.assertEqual(it.__length_hint__(), 1)
|
|
361
|
+
self.assertEqual(next(it), ('ee', 'fffff'))
|
|
362
|
+
self.assertEqual(it.__length_hint__(), 0)
|
|
363
|
+
with self.assertRaises(StopIteration):
|
|
364
|
+
next(it)
|
|
365
|
+
|
|
366
|
+
def test_array2d_tuple_iter_d(self) -> None:
|
|
367
|
+
a1 = np.array([['aaa', 'bb'], ['c', 'dd'], ['ee', 'fffff']])
|
|
368
|
+
it = array_to_tuple_iter(a1)
|
|
369
|
+
# __reversed__ not implemented
|
|
370
|
+
with self.assertRaises(TypeError):
|
|
371
|
+
reversed(it)
|
|
372
|
+
|
|
373
|
+
def test_array2d_tuple_iter_e(self) -> None:
|
|
374
|
+
a1 = np.array([[None, 'bb'], [None, 'dd'], [3, None]])
|
|
375
|
+
it = array_to_tuple_iter(a1)
|
|
376
|
+
del a1
|
|
377
|
+
self.assertEqual(list(it), [(None, 'bb'), (None, 'dd'), (3, None)])
|
|
378
|
+
|
|
379
|
+
def test_array2d_tuple_iter_f(self) -> None:
|
|
380
|
+
a1 = np.array([[None, 'bb'], [None, 'dd'], [3, None]])
|
|
381
|
+
it1 = array_to_tuple_iter(a1)
|
|
382
|
+
del a1
|
|
383
|
+
it2 = iter(it1)
|
|
384
|
+
self.assertEqual(list(it1), [(None, 'bb'), (None, 'dd'), (3, None)])
|
|
385
|
+
self.assertEqual(list(it2), []) # expected behavior
|
|
386
|
+
|
|
387
|
+
def test_array2d_tuple_iter_g(self) -> None:
|
|
388
|
+
a1 = np.array([[None, 'bb'], [None, 'dd'], [3, None]])
|
|
389
|
+
it1 = array_to_tuple_iter(a1)
|
|
390
|
+
it2 = array_to_tuple_iter(a1)
|
|
391
|
+
del a1
|
|
392
|
+
self.assertEqual(list(it1), [(None, 'bb'), (None, 'dd'), (3, None)])
|
|
393
|
+
self.assertEqual(list(it2), [(None, 'bb'), (None, 'dd'), (3, None)])
|
|
394
|
+
|
|
395
|
+
def test_array2d_tuple_iter_1d_a(self) -> None:
|
|
396
|
+
a1 = np.array(['bb', 'c', 'aaa'])
|
|
397
|
+
result = list(array_to_tuple_iter(a1))
|
|
398
|
+
self.assertEqual(len(result), 3)
|
|
399
|
+
self.assertEqual(result, [('bb',), ('c',), ('aaa',)])
|
|
400
|
+
|
|
401
|
+
def test_array2d_tuple_iter_1d_b(self) -> None:
|
|
402
|
+
a1 = np.array([20, -1, 8])
|
|
403
|
+
result = list(array_to_tuple_iter(a1))
|
|
404
|
+
self.assertEqual(len(result), 3)
|
|
405
|
+
self.assertEqual(result, [(20,), (-1,), (8,)])
|
|
406
|
+
|
|
407
|
+
def test_array2d_tuple_iter_1d_c(self) -> None:
|
|
408
|
+
a1 = np.array([('a', 4), ('c', -1), ('d', 8)], dtype=object)
|
|
409
|
+
result = list(array_to_tuple_iter(a1))
|
|
410
|
+
self.assertEqual(len(result), 3)
|
|
411
|
+
self.assertEqual(result, [('a', 4), ('c', -1), ('d', 8)])
|
|
412
|
+
|
|
286
413
|
#---------------------------------------------------------------------------
|
|
287
414
|
|
|
288
415
|
def test_isna_element_a(self) -> None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|