Skip to content

Commit e1f1251

Browse files
ogriseljreback
authored andcommitted
FIX make take_nd support readonly array
1 parent a03301f commit e1f1251

File tree

3 files changed

+2105
-306
lines changed

3 files changed

+2105
-306
lines changed

pandas/src/generate_code.py

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,7 @@ def take_1d_%(name)s_%(dest)s(ndarray[%(c_type_in)s] values,
9393
9494
"""
9595

96-
take_2d_axis0_template = """@cython.wraparound(False)
97-
@cython.boundscheck(False)
98-
def take_2d_axis0_%(name)s_%(dest)s(%(c_type_in)s[:, :] values,
99-
ndarray[int64_t] indexer,
100-
%(c_type_out)s[:, :] out,
101-
fill_value=np.nan):
96+
inner_take_2d_axis0_template = """\
10297
cdef:
10398
Py_ssize_t i, j, k, n, idx
10499
%(c_type_out)s fv
@@ -140,12 +135,34 @@ def take_2d_axis0_%(name)s_%(dest)s(%(c_type_in)s[:, :] values,
140135
141136
"""
142137

143-
take_2d_axis1_template = """@cython.wraparound(False)
138+
take_2d_axis0_template = """\
139+
@cython.wraparound(False)
144140
@cython.boundscheck(False)
145-
def take_2d_axis1_%(name)s_%(dest)s(%(c_type_in)s[:, :] values,
141+
cdef inline take_2d_axis0_%(name)s_%(dest)s_memview(%(c_type_in)s[:, :] values,
142+
ndarray[int64_t] indexer,
143+
%(c_type_out)s[:, :] out,
144+
fill_value=np.nan):
145+
""" + inner_take_2d_axis0_template + """
146+
147+
@cython.wraparound(False)
148+
@cython.boundscheck(False)
149+
def take_2d_axis0_%(name)s_%(dest)s(ndarray[%(c_type_in)s, ndim=2] values,
146150
ndarray[int64_t] indexer,
147151
%(c_type_out)s[:, :] out,
148152
fill_value=np.nan):
153+
if values.flags.writeable:
154+
# We can call the memoryview version of the code
155+
take_2d_axis0_%(name)s_%(dest)s_memview(values, indexer, out,
156+
fill_value=fill_value)
157+
return
158+
159+
# We cannot use the memoryview version on readonly-buffers due to
160+
# a limitation of Cython's typed memoryviews. Instead we can use
161+
# the slightly slower Cython ndarray type directly.
162+
""" + inner_take_2d_axis0_template
163+
164+
165+
inner_take_2d_axis1_template = """\
149166
cdef:
150167
Py_ssize_t i, j, k, n, idx
151168
%(c_type_out)s fv
@@ -165,9 +182,36 @@ def take_2d_axis1_%(name)s_%(dest)s(%(c_type_in)s[:, :] values,
165182
out[i, j] = fv
166183
else:
167184
out[i, j] = %(preval)svalues[i, idx]%(postval)s
168-
169185
"""
170186

187+
take_2d_axis1_template = """\
188+
@cython.wraparound(False)
189+
@cython.boundscheck(False)
190+
cdef inline take_2d_axis1_%(name)s_%(dest)s_memview(%(c_type_in)s[:, :] values,
191+
ndarray[int64_t] indexer,
192+
%(c_type_out)s[:, :] out,
193+
fill_value=np.nan):
194+
""" + inner_take_2d_axis1_template + """
195+
196+
@cython.wraparound(False)
197+
@cython.boundscheck(False)
198+
def take_2d_axis1_%(name)s_%(dest)s(ndarray[%(c_type_in)s, ndim=2] values,
199+
ndarray[int64_t] indexer,
200+
%(c_type_out)s[:, :] out,
201+
fill_value=np.nan):
202+
203+
if values.flags.writeable:
204+
# We can call the memoryview version of the code
205+
take_2d_axis1_%(name)s_%(dest)s_memview(values, indexer, out,
206+
fill_value=fill_value)
207+
return
208+
209+
# We cannot use the memoryview version on readonly-buffers due to
210+
# a limitation of Cython's typed memoryviews. Instead we can use
211+
# the slightly slower Cython ndarray type directly.
212+
""" + inner_take_2d_axis1_template
213+
214+
171215
take_2d_multi_template = """@cython.wraparound(False)
172216
@cython.boundscheck(False)
173217
def take_2d_multi_%(name)s_%(dest)s(ndarray[%(c_type_in)s, ndim=2] values,

0 commit comments

Comments
 (0)