@@ -36,87 +36,6 @@ dtypes = [
36
36
37
37
def get_dispatch(dtypes):
38
38
39
- inner_take_1d_template = """
40
- cdef:
41
- Py_ssize_t i, n, idx
42
- %(c_type_out)s fv
43
-
44
- n = indexer.shape[0]
45
-
46
- fv = fill_value
47
-
48
- %(nogil_str)s
49
- %(tab)sfor i from 0 <= i < n:
50
- %(tab)s idx = indexer[i]
51
- %(tab)s if idx == -1:
52
- %(tab)s out[i] = fv
53
- %(tab)s else:
54
- %(tab)s out[i] = %(preval)svalues[idx]%(postval)s
55
- """
56
-
57
- inner_take_2d_axis0_template = """\
58
- cdef:
59
- Py_ssize_t i, j, k, n, idx
60
- %(c_type_out)s fv
61
-
62
- n = len(indexer)
63
- k = values.shape[1]
64
-
65
- fv = fill_value
66
-
67
- IF %(can_copy)s:
68
- cdef:
69
- %(c_type_out)s *v
70
- %(c_type_out)s *o
71
-
72
- #GH3130
73
- if (values.strides[1] == out.strides[1] and
74
- values.strides[1] == sizeof(%(c_type_out)s) and
75
- sizeof(%(c_type_out)s) * n >= 256):
76
-
77
- for i from 0 <= i < n:
78
- idx = indexer[i]
79
- if idx == -1:
80
- for j from 0 <= j < k:
81
- out[i, j] = fv
82
- else:
83
- v = &values[idx, 0]
84
- o = &out[i, 0]
85
- memmove(o, v, <size_t>(sizeof(%(c_type_out)s) * k))
86
- return
87
-
88
- for i from 0 <= i < n:
89
- idx = indexer[i]
90
- if idx == -1:
91
- for j from 0 <= j < k:
92
- out[i, j] = fv
93
- else:
94
- for j from 0 <= j < k:
95
- out[i, j] = %(preval)svalues[idx, j]%(postval)s
96
- """
97
-
98
- inner_take_2d_axis1_template = """\
99
- cdef:
100
- Py_ssize_t i, j, k, n, idx
101
- %(c_type_out)s fv
102
-
103
- n = len(values)
104
- k = len(indexer)
105
-
106
- if n == 0 or k == 0:
107
- return
108
-
109
- fv = fill_value
110
-
111
- for i from 0 <= i < n:
112
- for j from 0 <= j < k:
113
- idx = indexer[j]
114
- if idx == -1:
115
- out[i, j] = fv
116
- else:
117
- out[i, j] = %(preval)svalues[i, idx]%(postval)s
118
- """
119
-
120
39
for (name, dest, c_type_in, c_type_out, preval, postval,
121
40
can_copy, nogil) in dtypes:
122
41
if nogil:
@@ -126,108 +45,112 @@ def get_dispatch(dtypes):
126
45
nogil_str = ''
127
46
tab = ''
128
47
129
- args = dict(name=name, dest=dest, c_type_in=c_type_in,
130
- c_type_out=c_type_out, preval=preval, postval=postval,
131
- can_copy=can_copy, nogil_str=nogil_str, tab=tab)
132
-
133
- inner_take_1d = inner_take_1d_template % args
134
- inner_take_2d_axis0 = inner_take_2d_axis0_template % args
135
- inner_take_2d_axis1 = inner_take_2d_axis1_template % args
136
-
137
48
yield (name, dest, c_type_in, c_type_out, preval, postval, can_copy,
138
- inner_take_1d, inner_take_2d_axis0, inner_take_2d_axis1 )
49
+ nogil_str, tab )
139
50
140
51
}}
141
52
142
53
143
54
{{for name, dest, c_type_in, c_type_out, preval, postval, can_copy,
144
- inner_take_1d, inner_take_2d_axis0, inner_take_2d_axis1
55
+ nogil_str, tab
145
56
in get_dispatch(dtypes)}}
146
57
147
58
148
59
@cython.wraparound(False)
149
60
@cython.boundscheck(False)
150
- cdef inline take_1d_{{name}}_{{dest}}_memview({{c_type_in}}[:] values,
151
- int64_t[:] indexer,
152
- {{c_type_out}}[:] out,
153
- fill_value=np.nan):
154
-
155
-
156
- {{inner_take_1d}}
157
-
158
-
159
- @cython.wraparound(False)
160
- @cython.boundscheck(False)
161
- def take_1d_{{name}}_{{dest}}(ndarray[{{c_type_in}}, ndim=1] values,
162
- int64_t[:] indexer,
61
+ def take_1d_{{name}}_{{dest}}({{if c_type_in != 'object'}}const{{endif}} {{c_type_in}}[:] values,
62
+ const int64_t[:] indexer,
163
63
{{c_type_out}}[:] out,
164
64
fill_value=np.nan):
65
+ cdef:
66
+ Py_ssize_t i, n, idx
67
+ {{c_type_out}} fv
165
68
166
- if values.flags.writeable:
167
- # We can call the memoryview version of the code
168
- take_1d_{{name}}_{{dest}}_memview(values, indexer, out,
169
- fill_value=fill_value)
170
- return
171
-
172
- # We cannot use the memoryview version on readonly-buffers due to
173
- # a limitation of Cython's typed memoryviews. Instead we can use
174
- # the slightly slower Cython ndarray type directly.
175
- {{inner_take_1d}}
69
+ n = indexer.shape[0]
176
70
71
+ fv = fill_value
177
72
178
- @cython.wraparound(False)
179
- @cython.boundscheck(False)
180
- cdef inline take_2d_axis0_{{name}}_{{dest}}_memview({{c_type_in}}[:, :] values,
181
- int64_t[:] indexer,
182
- {{c_type_out}}[:, :] out,
183
- fill_value=np.nan) :
184
- {{inner_take_2d_axis0 }}
73
+ {{nogil_str}}
74
+ {{tab}}for i from 0 <= i < n:
75
+ {{tab}} idx = indexer[i]
76
+ {{tab}} if idx == -1:
77
+ {{tab}} out[i] = fv
78
+ {{tab}} else :
79
+ {{tab}} out[i] = {{preval}}values[idx]{{postval }}
185
80
186
81
187
82
@cython.wraparound(False)
188
83
@cython.boundscheck(False)
189
- def take_2d_axis0_{{name}}_{{dest}}(ndarray[{{ c_type_in}}, ndim=2 ] values,
190
- ndarray[ int64_t] indexer,
84
+ def take_2d_axis0_{{name}}_{{dest}}({{if c_type_in != 'object'}}const{{endif}} {{c_type_in}}[:, : ] values,
85
+ const int64_t[: ] indexer,
191
86
{{c_type_out}}[:, :] out,
192
87
fill_value=np.nan):
193
- if values.flags.writeable:
194
- # We can call the memoryview version of the code
195
- take_2d_axis0_{{name}}_{{dest}}_memview(values, indexer, out,
196
- fill_value=fill_value)
197
- return
88
+ cdef:
89
+ Py_ssize_t i, j, k, n, idx
90
+ {{c_type_out}} fv
198
91
199
- # We cannot use the memoryview version on readonly-buffers due to
200
- # a limitation of Cython's typed memoryviews. Instead we can use
201
- # the slightly slower Cython ndarray type directly.
202
- {{inner_take_2d_axis0}}
92
+ n = len(indexer)
93
+ k = values.shape[1]
203
94
95
+ fv = fill_value
204
96
205
- @cython.wraparound(False)
206
- @cython.boundscheck(False)
207
- cdef inline take_2d_axis1_{{name}}_{{dest}}_memview({{c_type_in}}[:, :] values,
208
- int64_t[:] indexer,
209
- {{c_type_out}}[:, :] out,
210
- fill_value=np.nan):
211
- {{inner_take_2d_axis1}}
97
+ {{if can_copy}}
98
+ cdef:
99
+ {{c_type_out}} *v
100
+ {{c_type_out}} *o
101
+
102
+ #GH3130
103
+ if (values.strides[1] == out.strides[1] and
104
+ values.strides[1] == sizeof({{c_type_out}}) and
105
+ sizeof({{c_type_out}}) * n >= 256):
106
+
107
+ for i from 0 <= i < n:
108
+ idx = indexer[i]
109
+ if idx == -1:
110
+ for j from 0 <= j < k:
111
+ out[i, j] = fv
112
+ else:
113
+ v = &values[idx, 0]
114
+ o = &out[i, 0]
115
+ memmove(o, v, <size_t>(sizeof({{c_type_out}}) * k))
116
+ return
117
+ {{endif}}
118
+
119
+ for i from 0 <= i < n:
120
+ idx = indexer[i]
121
+ if idx == -1:
122
+ for j from 0 <= j < k:
123
+ out[i, j] = fv
124
+ else:
125
+ for j from 0 <= j < k:
126
+ out[i, j] = {{preval}}values[idx, j]{{postval}}
212
127
213
128
214
129
@cython.wraparound(False)
215
130
@cython.boundscheck(False)
216
- def take_2d_axis1_{{name}}_{{dest}}(ndarray[{{ c_type_in}}, ndim=2 ] values,
217
- ndarray[ int64_t] indexer,
131
+ def take_2d_axis1_{{name}}_{{dest}}({{if c_type_in != 'object'}}const{{endif}} {{c_type_in}}[:, : ] values,
132
+ const int64_t[: ] indexer,
218
133
{{c_type_out}}[:, :] out,
219
134
fill_value=np.nan):
135
+ cdef:
136
+ Py_ssize_t i, j, k, n, idx
137
+ {{c_type_out}} fv
220
138
221
- if values.flags.writeable:
222
- # We can call the memoryview version of the code
223
- take_2d_axis1_{{name}}_{{dest}}_memview(values, indexer, out,
224
- fill_value=fill_value)
139
+ n = len( values)
140
+ k = len(indexer)
141
+
142
+ if n == 0 or k == 0:
225
143
return
226
144
227
- # We cannot use the memoryview version on readonly-buffers due to
228
- # a limitation of Cython's typed memoryviews. Instead we can use
229
- # the slightly slower Cython ndarray type directly.
230
- {{inner_take_2d_axis1}}
145
+ fv = fill_value
146
+
147
+ for i from 0 <= i < n:
148
+ for j from 0 <= j < k:
149
+ idx = indexer[j]
150
+ if idx == -1:
151
+ out[i, j] = fv
152
+ else:
153
+ out[i, j] = {{preval}}values[i, idx]{{postval}}
231
154
232
155
233
156
@cython.wraparound(False)
0 commit comments