arraykit 0.7.0__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.7.0/arraykit.egg-info → arraykit-0.7.1}/PKG-INFO +1 -1
- {arraykit-0.7.0 → arraykit-0.7.1}/README.rst +9 -2
- {arraykit-0.7.0 → arraykit-0.7.1/arraykit.egg-info}/PKG-INFO +1 -1
- {arraykit-0.7.0 → arraykit-0.7.1}/setup.py +1 -1
- {arraykit-0.7.0 → arraykit-0.7.1}/src/__init__.py +2 -2
- {arraykit-0.7.0 → arraykit-0.7.1}/src/__init__.pyi +2 -2
- {arraykit-0.7.0 → arraykit-0.7.1}/src/_arraykit.c +102 -54
- {arraykit-0.7.0 → arraykit-0.7.1}/test/test_util.py +56 -18
- {arraykit-0.7.0 → arraykit-0.7.1}/LICENSE.txt +0 -0
- {arraykit-0.7.0 → arraykit-0.7.1}/MANIFEST.in +0 -0
- {arraykit-0.7.0 → arraykit-0.7.1}/arraykit.egg-info/SOURCES.txt +0 -0
- {arraykit-0.7.0 → arraykit-0.7.1}/arraykit.egg-info/dependency_links.txt +0 -0
- {arraykit-0.7.0 → arraykit-0.7.1}/arraykit.egg-info/requires.txt +0 -0
- {arraykit-0.7.0 → arraykit-0.7.1}/arraykit.egg-info/top_level.txt +0 -0
- {arraykit-0.7.0 → arraykit-0.7.1}/setup.cfg +0 -0
- {arraykit-0.7.0 → arraykit-0.7.1}/src/py.typed +0 -0
- {arraykit-0.7.0 → arraykit-0.7.1}/test/test_array_go.py +0 -0
- {arraykit-0.7.0 → arraykit-0.7.1}/test/test_block_index.py +0 -0
- {arraykit-0.7.0 → arraykit-0.7.1}/test/test_delimited_to_arrays.py +0 -0
- {arraykit-0.7.0 → arraykit-0.7.1}/test/test_delimited_to_arrays_integration.py +0 -0
- {arraykit-0.7.0 → arraykit-0.7.1}/test/test_delimited_to_arrays_property.py +0 -0
- {arraykit-0.7.0 → arraykit-0.7.1}/test/test_nonzero_1d.py +0 -0
- {arraykit-0.7.0 → arraykit-0.7.1}/test/test_nonzero_1d_property.py +0 -0
- {arraykit-0.7.0 → arraykit-0.7.1}/test/test_pyi.py +0 -0
- {arraykit-0.7.0 → arraykit-0.7.1}/test/test_split_after_count.py +0 -0
- {arraykit-0.7.0 → arraykit-0.7.1}/test/test_tri_map.py +0 -0
- {arraykit-0.7.0 → arraykit-0.7.1}/test/test_type_discovery.py +0 -0
|
@@ -37,12 +37,19 @@ 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
|
+
|
|
40
47
|
0.7.0
|
|
41
48
|
............
|
|
42
49
|
|
|
43
|
-
Added ``
|
|
50
|
+
Added ``array_to_tuple_array()``.
|
|
44
51
|
|
|
45
|
-
Added ``
|
|
52
|
+
Added ``array_to_tuple_iter()``.
|
|
46
53
|
|
|
47
54
|
|
|
48
55
|
0.6.3
|
|
@@ -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.7.
|
|
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,6 +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
|
|
32
|
-
from ._arraykit import
|
|
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
|
|
33
33
|
from ._arraykit import nonzero_1d as nonzero_1d
|
|
@@ -161,5 +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
|
|
165
|
-
def
|
|
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, ...]]: ...
|
|
@@ -3524,16 +3524,20 @@ array_deepcopy(PyObject *m, PyObject *args, PyObject *kwargs)
|
|
|
3524
3524
|
}
|
|
3525
3525
|
|
|
3526
3526
|
//------------------------------------------------------------------------------
|
|
3527
|
-
// Given a 2D array, return a 1D object array of tuples.
|
|
3527
|
+
// Given a 1D or 2D array, return a 1D object array of tuples.
|
|
3528
3528
|
static PyObject *
|
|
3529
|
-
|
|
3529
|
+
array_to_tuple_array(PyObject *Py_UNUSED(m), PyObject *a)
|
|
3530
3530
|
{
|
|
3531
|
-
|
|
3531
|
+
AK_CHECK_NUMPY_ARRAY(a);
|
|
3532
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
|
+
}
|
|
3533
3539
|
|
|
3534
3540
|
npy_intp num_rows = PyArray_DIM(input_array, 0);
|
|
3535
|
-
npy_intp num_cols = PyArray_DIM(input_array, 1);
|
|
3536
|
-
|
|
3537
3541
|
npy_intp dims[] = {num_rows};
|
|
3538
3542
|
// NOTE: this initializes values to NULL, not None
|
|
3539
3543
|
PyObject* output = PyArray_SimpleNew(1, dims, NPY_OBJECT);
|
|
@@ -3545,26 +3549,46 @@ array2d_to_array1d(PyObject *Py_UNUSED(m), PyObject *a)
|
|
|
3545
3549
|
PyObject** p = output_data;
|
|
3546
3550
|
PyObject** p_end = p + num_rows;
|
|
3547
3551
|
npy_intp i = 0;
|
|
3548
|
-
npy_intp j;
|
|
3549
3552
|
PyObject* tuple;
|
|
3550
3553
|
PyObject* item;
|
|
3551
3554
|
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
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++;
|
|
3556
3574
|
}
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
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);
|
|
3560
3584
|
if (item == NULL) {
|
|
3561
3585
|
Py_DECREF(tuple);
|
|
3562
3586
|
goto error;
|
|
3563
3587
|
}
|
|
3564
|
-
PyTuple_SET_ITEM(tuple,
|
|
3588
|
+
PyTuple_SET_ITEM(tuple, 0, item); // steals reference to item
|
|
3589
|
+
*p++ = tuple; // assign with new ref, no incr needed
|
|
3590
|
+
i++;
|
|
3565
3591
|
}
|
|
3566
|
-
*p++ = tuple; // assign with new ref, no incr needed
|
|
3567
|
-
i++;
|
|
3568
3592
|
}
|
|
3569
3593
|
PyArray_CLEARFLAGS((PyArrayObject *)output, NPY_ARRAY_WRITEABLE);
|
|
3570
3594
|
return output;
|
|
@@ -3579,65 +3603,81 @@ error:
|
|
|
3579
3603
|
}
|
|
3580
3604
|
|
|
3581
3605
|
//------------------------------------------------------------------------------
|
|
3582
|
-
//
|
|
3606
|
+
// ArrayToTupleIterator
|
|
3583
3607
|
|
|
3584
|
-
static PyTypeObject
|
|
3608
|
+
static PyTypeObject ATTType;
|
|
3585
3609
|
|
|
3586
|
-
typedef struct
|
|
3610
|
+
typedef struct ATTObject {
|
|
3587
3611
|
PyObject_HEAD
|
|
3588
3612
|
PyArrayObject* array;
|
|
3589
3613
|
npy_intp num_rows;
|
|
3590
3614
|
npy_intp num_cols;
|
|
3591
3615
|
Py_ssize_t pos; // current index state, mutated in-place
|
|
3592
|
-
}
|
|
3616
|
+
} ATTObject;
|
|
3593
3617
|
|
|
3594
3618
|
static PyObject *
|
|
3595
|
-
|
|
3619
|
+
ATT_new(PyArrayObject* array,
|
|
3596
3620
|
npy_intp num_rows,
|
|
3597
3621
|
npy_intp num_cols) {
|
|
3598
|
-
|
|
3622
|
+
ATTObject* a2dt = PyObject_New(ATTObject, &ATTType);
|
|
3599
3623
|
if (!a2dt) {
|
|
3600
3624
|
return NULL;
|
|
3601
3625
|
}
|
|
3602
3626
|
Py_INCREF((PyObject*)array);
|
|
3603
3627
|
a2dt->array = array;
|
|
3604
3628
|
a2dt->num_rows = num_rows;
|
|
3605
|
-
a2dt->num_cols = num_cols;
|
|
3629
|
+
a2dt->num_cols = num_cols; // -1 for 1D array
|
|
3606
3630
|
a2dt->pos = 0;
|
|
3607
3631
|
return (PyObject *)a2dt;
|
|
3608
3632
|
}
|
|
3609
3633
|
|
|
3610
3634
|
static void
|
|
3611
|
-
|
|
3635
|
+
ATT_dealloc(ATTObject *self) {
|
|
3612
3636
|
Py_DECREF((PyObject*)self->array);
|
|
3613
3637
|
PyObject_Del((PyObject*)self);
|
|
3614
3638
|
}
|
|
3615
3639
|
|
|
3616
3640
|
static PyObject*
|
|
3617
|
-
|
|
3641
|
+
ATT_iter(ATTObject *self) {
|
|
3618
3642
|
Py_INCREF(self);
|
|
3619
3643
|
return (PyObject*)self;
|
|
3620
3644
|
}
|
|
3621
3645
|
|
|
3622
3646
|
static PyObject *
|
|
3623
|
-
|
|
3647
|
+
ATT_iternext(ATTObject *self) {
|
|
3624
3648
|
Py_ssize_t i = self->pos;
|
|
3625
3649
|
if (i < self->num_rows) {
|
|
3626
3650
|
npy_intp num_cols = self->num_cols;
|
|
3627
3651
|
PyArrayObject* array = self->array;
|
|
3628
|
-
PyObject* tuple = PyTuple_New(num_cols);
|
|
3629
3652
|
PyObject* item;
|
|
3630
|
-
|
|
3631
|
-
|
|
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
|
+
}
|
|
3632
3669
|
}
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
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);
|
|
3636
3676
|
if (item == NULL) {
|
|
3637
3677
|
Py_DECREF(tuple);
|
|
3638
3678
|
return NULL;
|
|
3639
3679
|
}
|
|
3640
|
-
PyTuple_SET_ITEM(tuple,
|
|
3680
|
+
PyTuple_SET_ITEM(tuple, 0, item); // steals reference to item
|
|
3641
3681
|
}
|
|
3642
3682
|
self->pos++;
|
|
3643
3683
|
return tuple;
|
|
@@ -3646,44 +3686,52 @@ A2DTuple_iternext(A2DTupleObject *self) {
|
|
|
3646
3686
|
}
|
|
3647
3687
|
|
|
3648
3688
|
// static PyObject *
|
|
3649
|
-
//
|
|
3650
|
-
// return
|
|
3689
|
+
// ATT_reversed(ATTObject *self) {
|
|
3690
|
+
// return ATT_new(self->bi, !self->reversed);
|
|
3651
3691
|
// }
|
|
3652
3692
|
|
|
3653
3693
|
static PyObject *
|
|
3654
|
-
|
|
3694
|
+
ATT_length_hint(ATTObject *self) {
|
|
3655
3695
|
Py_ssize_t len = Py_MAX(0, self->num_rows - self->pos);
|
|
3656
3696
|
return PyLong_FromSsize_t(len);
|
|
3657
3697
|
}
|
|
3658
3698
|
|
|
3659
|
-
static PyMethodDef
|
|
3660
|
-
{"__length_hint__", (PyCFunction)
|
|
3661
|
-
// {"__reversed__", (PyCFunction)
|
|
3699
|
+
static PyMethodDef ATT_methods[] = {
|
|
3700
|
+
{"__length_hint__", (PyCFunction)ATT_length_hint, METH_NOARGS, NULL},
|
|
3701
|
+
// {"__reversed__", (PyCFunction)ATT_reversed, METH_NOARGS, NULL},
|
|
3662
3702
|
{NULL},
|
|
3663
3703
|
};
|
|
3664
3704
|
|
|
3665
|
-
static PyTypeObject
|
|
3705
|
+
static PyTypeObject ATTType = {
|
|
3666
3706
|
PyVarObject_HEAD_INIT(NULL, 0)
|
|
3667
|
-
.tp_basicsize = sizeof(
|
|
3668
|
-
.tp_dealloc = (destructor)
|
|
3669
|
-
.tp_iter = (getiterfunc)
|
|
3670
|
-
.tp_iternext = (iternextfunc)
|
|
3671
|
-
.tp_methods =
|
|
3672
|
-
.tp_name = "arraykit.
|
|
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",
|
|
3673
3713
|
};
|
|
3674
3714
|
|
|
3675
3715
|
// Given a 2D array, return an iterator of row tuples.
|
|
3676
3716
|
static PyObject *
|
|
3677
|
-
|
|
3717
|
+
array_to_tuple_iter(PyObject *Py_UNUSED(m), PyObject *a)
|
|
3678
3718
|
{
|
|
3679
|
-
|
|
3680
|
-
PyArrayObject*
|
|
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
|
+
}
|
|
3681
3727
|
npy_intp num_rows = PyArray_DIM(array, 0);
|
|
3682
|
-
npy_intp num_cols =
|
|
3683
|
-
|
|
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);
|
|
3684
3733
|
}
|
|
3685
3734
|
|
|
3686
|
-
|
|
3687
3735
|
//------------------------------------------------------------------------------
|
|
3688
3736
|
// type resolution
|
|
3689
3737
|
|
|
@@ -7431,8 +7479,8 @@ static PyMethodDef arraykit_methods[] = {
|
|
|
7431
7479
|
(PyCFunction)array_deepcopy,
|
|
7432
7480
|
METH_VARARGS | METH_KEYWORDS,
|
|
7433
7481
|
NULL},
|
|
7434
|
-
{"
|
|
7435
|
-
{"
|
|
7482
|
+
{"array_to_tuple_array", array_to_tuple_array, METH_O, NULL},
|
|
7483
|
+
{"array_to_tuple_iter", array_to_tuple_iter, METH_O, NULL},
|
|
7436
7484
|
{"resolve_dtype", resolve_dtype, METH_VARARGS, NULL},
|
|
7437
7485
|
{"resolve_dtype_iter", resolve_dtype_iter, METH_O, NULL},
|
|
7438
7486
|
{"first_true_1d",
|
|
@@ -22,8 +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
|
|
26
|
-
from arraykit import
|
|
25
|
+
from arraykit import array_to_tuple_array
|
|
26
|
+
from arraykit import array_to_tuple_iter
|
|
27
27
|
|
|
28
28
|
from performance.reference.util import get_new_indexers_and_screen_ak as get_new_indexers_and_screen_full
|
|
29
29
|
from arraykit import get_new_indexers_and_screen
|
|
@@ -286,15 +286,35 @@ class TestUnit(unittest.TestCase):
|
|
|
286
286
|
a2 = array_deepcopy(a1, ())
|
|
287
287
|
|
|
288
288
|
#---------------------------------------------------------------------------
|
|
289
|
-
def
|
|
289
|
+
def test_array2d_to_array1d_1d_a(self) -> None:
|
|
290
290
|
a1 = np.arange(10)
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
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,)])
|
|
294
314
|
|
|
295
315
|
def test_array2d_to_array1d_b(self) -> None:
|
|
296
316
|
a1 = np.arange(10, dtype=np.int64).reshape(5, 2)
|
|
297
|
-
result =
|
|
317
|
+
result = array_to_tuple_array(a1)
|
|
298
318
|
assert isinstance(result[0], tuple)
|
|
299
319
|
assert result[0] == (0, 1)
|
|
300
320
|
self.assertIs(type(result[0][0]), np.int64)
|
|
@@ -304,35 +324,35 @@ class TestUnit(unittest.TestCase):
|
|
|
304
324
|
|
|
305
325
|
def test_array2d_to_array1d_c(self) -> None:
|
|
306
326
|
a1 = np.array([["a", "b"], ["ccc", "ddd"], ["ee", "ff"]])
|
|
307
|
-
a2 =
|
|
327
|
+
a2 = array_to_tuple_array(a1)
|
|
308
328
|
self.assertEqual(a2.tolist(), [('a', 'b'), ('ccc', 'ddd'), ('ee', 'ff')])
|
|
309
329
|
|
|
310
330
|
def test_array2d_to_array1d_d(self) -> None:
|
|
311
331
|
a1 = np.array([[3, 5], [10, 20], [7, 2]], dtype=np.uint8)
|
|
312
|
-
a2 =
|
|
332
|
+
a2 = array_to_tuple_array(a1)
|
|
313
333
|
self.assertEqual(a2.tolist(), [(3, 5), (10, 20), (7, 2)])
|
|
314
334
|
self.assertIs(type(a2[0][0]), np.uint8)
|
|
315
335
|
|
|
316
336
|
def test_array2d_to_array1d_e(self) -> None:
|
|
317
337
|
a1 = np.arange(20, dtype=np.int64).reshape(4, 5)
|
|
318
|
-
result =
|
|
338
|
+
result = array_to_tuple_array(a1)
|
|
319
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)])
|
|
320
340
|
|
|
321
341
|
#---------------------------------------------------------------------------
|
|
322
342
|
def test_array2d_tuple_iter_a(self) -> None:
|
|
323
343
|
a1 = np.arange(20, dtype=np.int64).reshape(4, 5)
|
|
324
|
-
result = list(
|
|
344
|
+
result = list(array_to_tuple_iter(a1))
|
|
325
345
|
self.assertEqual(len(result), 4)
|
|
326
346
|
self.assertEqual(result, [(0, 1, 2, 3, 4), (5, 6, 7, 8, 9), (10, 11, 12, 13, 14), (15, 16, 17, 18, 19)])
|
|
327
347
|
|
|
328
348
|
def test_array2d_tuple_iter_b(self) -> None:
|
|
329
349
|
a1 = np.arange(20, dtype=np.int64).reshape(10, 2)
|
|
330
|
-
result = list(
|
|
350
|
+
result = list(array_to_tuple_iter(a1))
|
|
331
351
|
self.assertEqual(result, [(0, 1), (2, 3), (4, 5), (6, 7), (8, 9), (10, 11), (12, 13), (14, 15), (16, 17), (18, 19)])
|
|
332
352
|
|
|
333
353
|
def test_array2d_tuple_iter_c(self) -> None:
|
|
334
354
|
a1 = np.array([['aaa', 'bb'], ['c', 'dd'], ['ee', 'fffff']])
|
|
335
|
-
it =
|
|
355
|
+
it = array_to_tuple_iter(a1)
|
|
336
356
|
self.assertEqual(it.__length_hint__(), 3)
|
|
337
357
|
self.assertEqual(next(it), ('aaa', 'bb'))
|
|
338
358
|
self.assertEqual(it.__length_hint__(), 2)
|
|
@@ -345,20 +365,20 @@ class TestUnit(unittest.TestCase):
|
|
|
345
365
|
|
|
346
366
|
def test_array2d_tuple_iter_d(self) -> None:
|
|
347
367
|
a1 = np.array([['aaa', 'bb'], ['c', 'dd'], ['ee', 'fffff']])
|
|
348
|
-
it =
|
|
368
|
+
it = array_to_tuple_iter(a1)
|
|
349
369
|
# __reversed__ not implemented
|
|
350
370
|
with self.assertRaises(TypeError):
|
|
351
371
|
reversed(it)
|
|
352
372
|
|
|
353
373
|
def test_array2d_tuple_iter_e(self) -> None:
|
|
354
374
|
a1 = np.array([[None, 'bb'], [None, 'dd'], [3, None]])
|
|
355
|
-
it =
|
|
375
|
+
it = array_to_tuple_iter(a1)
|
|
356
376
|
del a1
|
|
357
377
|
self.assertEqual(list(it), [(None, 'bb'), (None, 'dd'), (3, None)])
|
|
358
378
|
|
|
359
379
|
def test_array2d_tuple_iter_f(self) -> None:
|
|
360
380
|
a1 = np.array([[None, 'bb'], [None, 'dd'], [3, None]])
|
|
361
|
-
it1 =
|
|
381
|
+
it1 = array_to_tuple_iter(a1)
|
|
362
382
|
del a1
|
|
363
383
|
it2 = iter(it1)
|
|
364
384
|
self.assertEqual(list(it1), [(None, 'bb'), (None, 'dd'), (3, None)])
|
|
@@ -366,12 +386,30 @@ class TestUnit(unittest.TestCase):
|
|
|
366
386
|
|
|
367
387
|
def test_array2d_tuple_iter_g(self) -> None:
|
|
368
388
|
a1 = np.array([[None, 'bb'], [None, 'dd'], [3, None]])
|
|
369
|
-
it1 =
|
|
370
|
-
it2 =
|
|
389
|
+
it1 = array_to_tuple_iter(a1)
|
|
390
|
+
it2 = array_to_tuple_iter(a1)
|
|
371
391
|
del a1
|
|
372
392
|
self.assertEqual(list(it1), [(None, 'bb'), (None, 'dd'), (3, None)])
|
|
373
393
|
self.assertEqual(list(it2), [(None, 'bb'), (None, 'dd'), (3, None)])
|
|
374
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
|
+
|
|
375
413
|
#---------------------------------------------------------------------------
|
|
376
414
|
|
|
377
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
|