forked from pandas-dev/pandas
-
Notifications
You must be signed in to change notification settings - Fork 3
/
numpy_helper.h
157 lines (127 loc) · 4.44 KB
/
numpy_helper.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
Copyright (c) 2016, PyData Development Team
All rights reserved.
Distributed under the terms of the BSD Simplified License.
The full license is in the LICENSE file, distributed with this software.
*/
#ifndef PANDAS__LIBS_SRC_NUMPY_HELPER_H_
#define PANDAS__LIBS_SRC_NUMPY_HELPER_H_
#include "Python.h"
#include "helper.h"
#include "numpy/arrayobject.h"
#include "numpy/arrayscalars.h"
#define PANDAS_FLOAT 0
#define PANDAS_INT 1
#define PANDAS_BOOL 2
#define PANDAS_STRING 3
#define PANDAS_OBJECT 4
#define PANDAS_DATETIME 5
PANDAS_INLINE int infer_type(PyObject* obj) {
if (PyBool_Check(obj)) {
return PANDAS_BOOL;
} else if (PyArray_IsIntegerScalar(obj)) {
return PANDAS_INT;
} else if (PyArray_IsScalar(obj, Datetime)) {
return PANDAS_DATETIME;
} else if (PyFloat_Check(obj) || PyArray_IsScalar(obj, Floating)) {
return PANDAS_FLOAT;
} else if (PyString_Check(obj) || PyUnicode_Check(obj)) {
return PANDAS_STRING;
} else {
return PANDAS_OBJECT;
}
}
PANDAS_INLINE npy_int64 get_nat(void) { return NPY_MIN_INT64; }
PANDAS_INLINE npy_datetime get_datetime64_value(PyObject* obj) {
return ((PyDatetimeScalarObject*)obj)->obval;
}
PANDAS_INLINE npy_timedelta get_timedelta64_value(PyObject* obj) {
return ((PyTimedeltaScalarObject*)obj)->obval;
}
PANDAS_INLINE int is_integer_object(PyObject* obj) {
return (!PyBool_Check(obj)) && PyArray_IsIntegerScalar(obj);
}
PANDAS_INLINE int is_float_object(PyObject* obj) {
return (PyFloat_Check(obj) || PyArray_IsScalar(obj, Floating));
}
PANDAS_INLINE int is_complex_object(PyObject* obj) {
return (PyComplex_Check(obj) || PyArray_IsScalar(obj, ComplexFloating));
}
PANDAS_INLINE int is_bool_object(PyObject* obj) {
return (PyBool_Check(obj) || PyArray_IsScalar(obj, Bool));
}
PANDAS_INLINE int is_string_object(PyObject* obj) {
return (PyString_Check(obj) || PyUnicode_Check(obj));
}
PANDAS_INLINE int is_datetime64_object(PyObject* obj) {
return PyArray_IsScalar(obj, Datetime);
}
PANDAS_INLINE int is_timedelta64_object(PyObject* obj) {
return PyArray_IsScalar(obj, Timedelta);
}
PANDAS_INLINE int assign_value_1d(PyArrayObject* ap, Py_ssize_t _i,
PyObject* v) {
npy_intp i = (npy_intp)_i;
char* item = (char*)PyArray_DATA(ap) + i * PyArray_STRIDE(ap, 0);
return PyArray_DESCR(ap)->f->setitem(v, item, ap);
}
PANDAS_INLINE PyObject* get_value_1d(PyArrayObject* ap, Py_ssize_t i) {
char* item = (char*)PyArray_DATA(ap) + i * PyArray_STRIDE(ap, 0);
return PyArray_Scalar(item, PyArray_DESCR(ap), (PyObject*)ap);
}
// returns ASCII or UTF8 (py3) view on python str
// python object owns memory, should not be freed
PANDAS_INLINE char* get_c_string(PyObject* obj) {
#if PY_VERSION_HEX >= 0x03000000
return PyUnicode_AsUTF8(obj);
#else
return PyString_AsString(obj);
#endif
}
PANDAS_INLINE PyObject* char_to_string(char* data) {
#if PY_VERSION_HEX >= 0x03000000
return PyUnicode_FromString(data);
#else
return PyString_FromString(data);
#endif
}
PyObject* sarr_from_data(PyArray_Descr* descr, int length, void* data) {
PyArrayObject* result;
npy_intp dims[1] = {length};
Py_INCREF(descr); // newfromdescr steals a reference to descr
result = (PyArrayObject*)PyArray_NewFromDescr(&PyArray_Type, descr, 1, dims,
NULL, data, 0, NULL);
// Returned array doesn't own data by default
result->flags |= NPY_OWNDATA;
return (PyObject*)result;
}
void transfer_object_column(char* dst, char* src, size_t stride,
size_t length) {
size_t i;
size_t sz = sizeof(PyObject*);
for (i = 0; i < length; ++i) {
// uninitialized data
// Py_XDECREF(*((PyObject**) dst));
memcpy(dst, src, sz);
Py_INCREF(*((PyObject**)dst));
src += sz;
dst += stride;
}
}
void set_array_owndata(PyArrayObject* ao) { ao->flags |= NPY_OWNDATA; }
void set_array_not_contiguous(PyArrayObject* ao) {
ao->flags &= ~(NPY_C_CONTIGUOUS | NPY_F_CONTIGUOUS);
}
// If arr is zerodim array, return a proper array scalar (e.g. np.int64).
// Otherwise, return arr as is.
PANDAS_INLINE PyObject* unbox_if_zerodim(PyObject* arr) {
if (PyArray_IsZeroDim(arr)) {
PyObject* ret;
ret = PyArray_ToScalar(PyArray_DATA(arr), arr);
return ret;
} else {
Py_INCREF(arr);
return arr;
}
}
#endif // PANDAS__LIBS_SRC_NUMPY_HELPER_H_