arraykit 0.6.2__tar.gz → 0.6.3__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.2/arraykit.egg-info → arraykit-0.6.3}/PKG-INFO +1 -1
- {arraykit-0.6.2 → arraykit-0.6.3}/README.rst +7 -1
- {arraykit-0.6.2 → arraykit-0.6.3/arraykit.egg-info}/PKG-INFO +1 -1
- {arraykit-0.6.2 → arraykit-0.6.3}/setup.py +1 -1
- {arraykit-0.6.2 → arraykit-0.6.3}/src/_arraykit.c +35 -62
- {arraykit-0.6.2 → arraykit-0.6.3}/LICENSE.txt +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/MANIFEST.in +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/arraykit.egg-info/SOURCES.txt +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/arraykit.egg-info/dependency_links.txt +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/arraykit.egg-info/requires.txt +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/arraykit.egg-info/top_level.txt +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/setup.cfg +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/src/__init__.py +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/src/__init__.pyi +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/src/py.typed +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/test/test_array_go.py +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/test/test_block_index.py +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/test/test_delimited_to_arrays.py +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/test/test_delimited_to_arrays_integration.py +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/test/test_delimited_to_arrays_property.py +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/test/test_nonzero_1d.py +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/test/test_nonzero_1d_property.py +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/test/test_pyi.py +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/test/test_split_after_count.py +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/test/test_tri_map.py +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/test/test_type_discovery.py +0 -0
- {arraykit-0.6.2 → arraykit-0.6.3}/test/test_util.py +0 -0
|
@@ -37,10 +37,16 @@ ArrayKit requires the following:
|
|
|
37
37
|
What is New in ArrayKit
|
|
38
38
|
-------------------------
|
|
39
39
|
|
|
40
|
+
0.6.3
|
|
41
|
+
............
|
|
42
|
+
|
|
43
|
+
Optimized memory allocation strategy for ``nonzero_1d()``.
|
|
44
|
+
|
|
45
|
+
|
|
40
46
|
0.6.2
|
|
41
47
|
............
|
|
42
48
|
|
|
43
|
-
Extended ``nonzero_1d()`` to support non-contiguous arrays
|
|
49
|
+
Extended ``nonzero_1d()`` to support non-contiguous arrays.
|
|
44
50
|
|
|
45
51
|
Optimizations to ``TriMap`` when mapping to object and flexible dtypes.
|
|
46
52
|
|
|
@@ -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.6.
|
|
8
|
+
AK_VERSION = '0.6.3'
|
|
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.
|
|
@@ -836,9 +836,9 @@ AK_TP_ResolveLineResetField(AK_TypeParser* tp,
|
|
|
836
836
|
static char* TRUE_LOWER = "true";
|
|
837
837
|
static char* TRUE_UPPER = "TRUE";
|
|
838
838
|
|
|
839
|
-
#define
|
|
840
|
-
#define
|
|
841
|
-
#define
|
|
839
|
+
#define AK_ERROR_NO_DIGITS 1
|
|
840
|
+
#define AK_ERROR_OVERFLOW 2
|
|
841
|
+
#define AK_ERROR_INVALID_CHARS 3
|
|
842
842
|
|
|
843
843
|
// Convert a Py_UCS4 array to a signed integer. Extended from pandas/_libs/src/parser/tokenizer.c. Sets `error` to values greater than 0 on error; never sets error on success.
|
|
844
844
|
static inline npy_int64
|
|
@@ -866,7 +866,7 @@ AK_UCS4_to_int64(Py_UCS4 *p_item, Py_UCS4 *end, int *error, char tsep)
|
|
|
866
866
|
|
|
867
867
|
// Check that there is a first digit.
|
|
868
868
|
if (!AK_is_digit(*p)) {
|
|
869
|
-
*error =
|
|
869
|
+
*error = AK_ERROR_NO_DIGITS;
|
|
870
870
|
return 0;
|
|
871
871
|
}
|
|
872
872
|
if (isneg) {
|
|
@@ -891,7 +891,7 @@ AK_UCS4_to_int64(Py_UCS4 *p_item, Py_UCS4 *end, int *error, char tsep)
|
|
|
891
891
|
if (p >= end) return number;
|
|
892
892
|
d = *p;
|
|
893
893
|
} else {
|
|
894
|
-
*error =
|
|
894
|
+
*error = AK_ERROR_OVERFLOW;
|
|
895
895
|
return 0;
|
|
896
896
|
}
|
|
897
897
|
}
|
|
@@ -904,7 +904,7 @@ AK_UCS4_to_int64(Py_UCS4 *p_item, Py_UCS4 *end, int *error, char tsep)
|
|
|
904
904
|
if (p >= end) return number;
|
|
905
905
|
d = *p;
|
|
906
906
|
} else {
|
|
907
|
-
*error =
|
|
907
|
+
*error = AK_ERROR_OVERFLOW;
|
|
908
908
|
return 0;
|
|
909
909
|
}
|
|
910
910
|
}
|
|
@@ -931,7 +931,7 @@ AK_UCS4_to_int64(Py_UCS4 *p_item, Py_UCS4 *end, int *error, char tsep)
|
|
|
931
931
|
if (p >= end) return number;
|
|
932
932
|
d = *p;
|
|
933
933
|
} else {
|
|
934
|
-
*error =
|
|
934
|
+
*error = AK_ERROR_OVERFLOW;
|
|
935
935
|
return 0;
|
|
936
936
|
}
|
|
937
937
|
}
|
|
@@ -944,7 +944,7 @@ AK_UCS4_to_int64(Py_UCS4 *p_item, Py_UCS4 *end, int *error, char tsep)
|
|
|
944
944
|
if (p >= end) return number;
|
|
945
945
|
d = *p;
|
|
946
946
|
} else {
|
|
947
|
-
*error =
|
|
947
|
+
*error = AK_ERROR_OVERFLOW;
|
|
948
948
|
return 0;
|
|
949
949
|
}
|
|
950
950
|
}
|
|
@@ -952,7 +952,7 @@ AK_UCS4_to_int64(Py_UCS4 *p_item, Py_UCS4 *end, int *error, char tsep)
|
|
|
952
952
|
}
|
|
953
953
|
while (p < end) {
|
|
954
954
|
if (!AK_is_space(*p)) {
|
|
955
|
-
*error =
|
|
955
|
+
*error = AK_ERROR_INVALID_CHARS;
|
|
956
956
|
return 0;
|
|
957
957
|
}
|
|
958
958
|
p++;
|
|
@@ -975,7 +975,7 @@ AK_UCS4_to_uint64(Py_UCS4 *p_item, Py_UCS4 *end, int *error, char tsep)
|
|
|
975
975
|
if (p >= end) return number;
|
|
976
976
|
}
|
|
977
977
|
if (*p == '-') {
|
|
978
|
-
*error =
|
|
978
|
+
*error = AK_ERROR_INVALID_CHARS;
|
|
979
979
|
return 0;
|
|
980
980
|
} else if (*p == '+') {
|
|
981
981
|
p++;
|
|
@@ -984,7 +984,7 @@ AK_UCS4_to_uint64(Py_UCS4 *p_item, Py_UCS4 *end, int *error, char tsep)
|
|
|
984
984
|
|
|
985
985
|
// Check that there is a first digit.
|
|
986
986
|
if (!AK_is_digit(*p)) {
|
|
987
|
-
*error =
|
|
987
|
+
*error = AK_ERROR_NO_DIGITS;
|
|
988
988
|
return 0;
|
|
989
989
|
}
|
|
990
990
|
// If number is less than pre_max, at least one more digit can be processed without overflowing.
|
|
@@ -1006,7 +1006,7 @@ AK_UCS4_to_uint64(Py_UCS4 *p_item, Py_UCS4 *end, int *error, char tsep)
|
|
|
1006
1006
|
if (p >= end) return number;
|
|
1007
1007
|
d = *p;
|
|
1008
1008
|
} else {
|
|
1009
|
-
*error =
|
|
1009
|
+
*error = AK_ERROR_OVERFLOW;
|
|
1010
1010
|
return 0;
|
|
1011
1011
|
}
|
|
1012
1012
|
}
|
|
@@ -1019,14 +1019,14 @@ AK_UCS4_to_uint64(Py_UCS4 *p_item, Py_UCS4 *end, int *error, char tsep)
|
|
|
1019
1019
|
if (p >= end) return number;
|
|
1020
1020
|
d = *p;
|
|
1021
1021
|
} else {
|
|
1022
|
-
*error =
|
|
1022
|
+
*error = AK_ERROR_OVERFLOW;
|
|
1023
1023
|
return 0;
|
|
1024
1024
|
}
|
|
1025
1025
|
}
|
|
1026
1026
|
}
|
|
1027
1027
|
while (p < end) {
|
|
1028
1028
|
if (!AK_is_space(*p)) {
|
|
1029
|
-
*error =
|
|
1029
|
+
*error = AK_ERROR_INVALID_CHARS;
|
|
1030
1030
|
return 0;
|
|
1031
1031
|
}
|
|
1032
1032
|
p++;
|
|
@@ -3535,32 +3535,9 @@ resolve_dtype_iter(PyObject *Py_UNUSED(m), PyObject *arg) {
|
|
|
3535
3535
|
//------------------------------------------------------------------------------
|
|
3536
3536
|
// general utility
|
|
3537
3537
|
|
|
3538
|
-
|
|
3539
|
-
if (AK_UNLIKELY(count == capacity)) { \
|
|
3540
|
-
capacity <<= 1; \
|
|
3541
|
-
indices = (npy_int64*)realloc(indices, sizeof(npy_int64) * capacity);\
|
|
3542
|
-
if (indices == NULL) { \
|
|
3543
|
-
return NULL; \
|
|
3544
|
-
} \
|
|
3545
|
-
} \
|
|
3546
|
-
indices[count++] = p - p_start; \
|
|
3547
|
-
} \
|
|
3548
|
-
|
|
3549
|
-
#define NONZERO_APPEND_INDEX_ABSOLUTE { \
|
|
3550
|
-
if (AK_UNLIKELY(count == capacity)) { \
|
|
3551
|
-
capacity <<= 1; \
|
|
3552
|
-
indices = (npy_int64*)realloc(indices, sizeof(npy_int64) * capacity);\
|
|
3553
|
-
if (indices == NULL) { \
|
|
3554
|
-
return NULL; \
|
|
3555
|
-
} \
|
|
3556
|
-
} \
|
|
3557
|
-
indices[count++] = i; \
|
|
3558
|
-
} \
|
|
3559
|
-
|
|
3560
|
-
// Given a Boolean, contiguous 1D array, return the index positions in an int64 array. Through experimentation it has been verified that doing full-size allocation of memory does not permit outperforming NumPy at 10_000_000 scale; but doing less optimizations does help. Using bit masks does not improve perforamnce over pointer arithmetic. Prescanning for all empty is very effective. Note that NumPy befits from first counting the nonzeros, then allocating only enough data for the expexted number.
|
|
3538
|
+
// Given a Boolean, contiguous 1D array, return the index positions in an int64 array. Through experimentation it has been verified that doing full-size allocation of memory provides the best performance at all scales. Using NpyIter, or using, bit masks does not improve performance over pointer arithmetic. Prescanning for all empty is very effective. Note that NumPy benefits from first counting the nonzeros, then allocating only enough data for the expexted number of indices.
|
|
3561
3539
|
static inline PyObject*
|
|
3562
3540
|
AK_nonzero_1d(PyArrayObject* array) {
|
|
3563
|
-
// the maxiumum number of indices we could return is the size of the array; if this is under a certain number, probably better to just allocate that rather than reallocate
|
|
3564
3541
|
PyObject* final;
|
|
3565
3542
|
npy_intp count_max = PyArray_SIZE(array);
|
|
3566
3543
|
|
|
@@ -3573,8 +3550,8 @@ AK_nonzero_1d(PyArrayObject* array) {
|
|
|
3573
3550
|
lldiv_t size_div = lldiv((long long)count_max, 8); // quot, rem
|
|
3574
3551
|
|
|
3575
3552
|
Py_ssize_t count = 0;
|
|
3576
|
-
// the maximum number of collected integers is equal to or less than count_max
|
|
3577
|
-
Py_ssize_t capacity = count_max
|
|
3553
|
+
// the maximum number of collected integers is equal to or less than count_max
|
|
3554
|
+
Py_ssize_t capacity = count_max;
|
|
3578
3555
|
npy_int64* indices = (npy_int64*)malloc(sizeof(npy_int64) * capacity);
|
|
3579
3556
|
|
|
3580
3557
|
NPY_BEGIN_THREADS_DEF;
|
|
@@ -3591,25 +3568,25 @@ AK_nonzero_1d(PyArrayObject* array) {
|
|
|
3591
3568
|
p += 8; // no true within this 8 byte roll region
|
|
3592
3569
|
continue;
|
|
3593
3570
|
}
|
|
3594
|
-
if (*p) {
|
|
3571
|
+
if (*p) {indices[count++] = p - p_start;}
|
|
3595
3572
|
p++;
|
|
3596
|
-
if (*p) {
|
|
3573
|
+
if (*p) {indices[count++] = p - p_start;}
|
|
3597
3574
|
p++;
|
|
3598
|
-
if (*p) {
|
|
3575
|
+
if (*p) {indices[count++] = p - p_start;}
|
|
3599
3576
|
p++;
|
|
3600
|
-
if (*p) {
|
|
3577
|
+
if (*p) {indices[count++] = p - p_start;}
|
|
3601
3578
|
p++;
|
|
3602
|
-
if (*p) {
|
|
3579
|
+
if (*p) {indices[count++] = p - p_start;}
|
|
3603
3580
|
p++;
|
|
3604
|
-
if (*p) {
|
|
3581
|
+
if (*p) {indices[count++] = p - p_start;}
|
|
3605
3582
|
p++;
|
|
3606
|
-
if (*p) {
|
|
3583
|
+
if (*p) {indices[count++] = p - p_start;}
|
|
3607
3584
|
p++;
|
|
3608
|
-
if (*p) {
|
|
3585
|
+
if (*p) {indices[count++] = p - p_start;}
|
|
3609
3586
|
p++;
|
|
3610
3587
|
}
|
|
3611
3588
|
while (p < p_end) {
|
|
3612
|
-
if (*p) {
|
|
3589
|
+
if (*p) {indices[count++] = p - p_start;}
|
|
3613
3590
|
p++;
|
|
3614
3591
|
}
|
|
3615
3592
|
}
|
|
@@ -3618,25 +3595,25 @@ AK_nonzero_1d(PyArrayObject* array) {
|
|
|
3618
3595
|
npy_intp i_end = count_max;
|
|
3619
3596
|
npy_intp i_end_roll = count_max - size_div.rem;
|
|
3620
3597
|
while (i < i_end_roll) {
|
|
3621
|
-
if (*(npy_bool*)PyArray_GETPTR1(array, i)) {
|
|
3598
|
+
if (*(npy_bool*)PyArray_GETPTR1(array, i)) {indices[count++] = i;}
|
|
3622
3599
|
i++;
|
|
3623
|
-
if (*(npy_bool*)PyArray_GETPTR1(array, i)) {
|
|
3600
|
+
if (*(npy_bool*)PyArray_GETPTR1(array, i)) {indices[count++] = i;}
|
|
3624
3601
|
i++;
|
|
3625
|
-
if (*(npy_bool*)PyArray_GETPTR1(array, i)) {
|
|
3602
|
+
if (*(npy_bool*)PyArray_GETPTR1(array, i)) {indices[count++] = i;}
|
|
3626
3603
|
i++;
|
|
3627
|
-
if (*(npy_bool*)PyArray_GETPTR1(array, i)) {
|
|
3604
|
+
if (*(npy_bool*)PyArray_GETPTR1(array, i)) {indices[count++] = i;}
|
|
3628
3605
|
i++;
|
|
3629
|
-
if (*(npy_bool*)PyArray_GETPTR1(array, i)) {
|
|
3606
|
+
if (*(npy_bool*)PyArray_GETPTR1(array, i)) {indices[count++] = i;}
|
|
3630
3607
|
i++;
|
|
3631
|
-
if (*(npy_bool*)PyArray_GETPTR1(array, i)) {
|
|
3608
|
+
if (*(npy_bool*)PyArray_GETPTR1(array, i)) {indices[count++] = i;}
|
|
3632
3609
|
i++;
|
|
3633
|
-
if (*(npy_bool*)PyArray_GETPTR1(array, i)) {
|
|
3610
|
+
if (*(npy_bool*)PyArray_GETPTR1(array, i)) {indices[count++] = i;}
|
|
3634
3611
|
i++;
|
|
3635
|
-
if (*(npy_bool*)PyArray_GETPTR1(array, i)) {
|
|
3612
|
+
if (*(npy_bool*)PyArray_GETPTR1(array, i)) {indices[count++] = i;}
|
|
3636
3613
|
i++;
|
|
3637
3614
|
}
|
|
3638
3615
|
while (i < i_end) {
|
|
3639
|
-
if (*(npy_bool*)PyArray_GETPTR1(array, i)) {
|
|
3616
|
+
if (*(npy_bool*)PyArray_GETPTR1(array, i)) {indices[count++] = i;}
|
|
3640
3617
|
i++;
|
|
3641
3618
|
}
|
|
3642
3619
|
}
|
|
@@ -3653,8 +3630,6 @@ AK_nonzero_1d(PyArrayObject* array) {
|
|
|
3653
3630
|
PyArray_CLEARFLAGS((PyArrayObject*)final, NPY_ARRAY_WRITEABLE);
|
|
3654
3631
|
return final;
|
|
3655
3632
|
}
|
|
3656
|
-
#undef NONZERO_APPEND_INDEX_RELATIVE
|
|
3657
|
-
#undef NONZERO_APPEND_INDEX_ABSOLUTE
|
|
3658
3633
|
|
|
3659
3634
|
static PyObject*
|
|
3660
3635
|
nonzero_1d(PyObject *Py_UNUSED(m), PyObject *a) {
|
|
@@ -6102,14 +6077,12 @@ TriMap_register_unmatched_dst(TriMapObject *self) {
|
|
|
6102
6077
|
return NULL;
|
|
6103
6078
|
}
|
|
6104
6079
|
// derive indices for unmatched locations, call each with register_one
|
|
6105
|
-
// PyObject* nonzero = PyArray_Nonzero(dst_unmatched);
|
|
6106
6080
|
PyArrayObject* indices = (PyArrayObject*)AK_nonzero_1d(dst_unmatched);
|
|
6107
6081
|
if (indices == NULL) {
|
|
6108
6082
|
Py_DECREF((PyObject*)dst_unmatched);
|
|
6109
6083
|
return NULL;
|
|
6110
6084
|
}
|
|
6111
6085
|
// borrow ref to array in 1-element tuple
|
|
6112
|
-
// PyArrayObject *indices = (PyArrayObject*)PyTuple_GET_ITEM(nonzero, 0);
|
|
6113
6086
|
npy_int64 *index_data = (npy_int64 *)PyArray_DATA(indices);
|
|
6114
6087
|
npy_intp index_len = PyArray_SIZE(indices);
|
|
6115
6088
|
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|