Skip to content

Commit 33473b3

Browse files
committed
fix: NumPy syntax now handles dd
1 parent 3771643 commit 33473b3

File tree

4 files changed

+96
-7
lines changed

4 files changed

+96
-7
lines changed

src/boost_histogram/_internal/hist.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,18 +454,36 @@ def _compute_commonindex(self, index):
454454

455455
return indexes
456456

457-
def to_numpy(self, flow=False):
457+
@inject_signature("self, flow=False, *, dd=False")
458+
def to_numpy(self, flow=False, **kwargs):
458459
"""
459460
Convert to a Numpy style tuple of return arrays.
460461
462+
Parameters
463+
----------
464+
465+
flow : bool = False
466+
Include the flow bins.
467+
dd : bool = False
468+
Use the histogramdd return syntax, where the edges are in a tuple
469+
461470
Return
462471
------
463472
contents : Array[Any]
464473
The bin contents
465474
*edges : Array[float]
466475
The edges for each dimension
467476
"""
468-
return self._hist.to_numpy(flow)
477+
478+
with KWArgs(kwargs) as kw:
479+
dd = kw.optional("dd", False)
480+
481+
return_tuple = self._hist.to_numpy(flow)
482+
483+
if dd:
484+
return return_tuple[0], return_tuple[1:]
485+
else:
486+
return return_tuple
469487

470488
@inject_signature("self, *, deep=True")
471489
def copy(self, **kwargs):

src/boost_histogram/numpy.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ def histogramdd(
7878
if density:
7979
areas = _reduce(_mul, hist.axes.widths)
8080
density = hist.view() / hist.sum() / areas
81-
return (density,) + hist.to_numpy()[1:]
81+
return (density, hist.to_numpy()[1:])
8282

83-
return hist if bh_cls is not None else hist.to_numpy()
83+
return hist if bh_cls is not None else hist.to_numpy(dd=True)
8484

8585

8686
@_inject_signature(
@@ -89,7 +89,13 @@ def histogramdd(
8989
def histogram2d(
9090
x, y, bins=10, range=None, normed=None, weights=None, density=None, **kwargs
9191
):
92-
return histogramdd((x, y), bins, range, normed, weights, density, **kwargs)
92+
result = histogramdd((x, y), bins, range, normed, weights, density, **kwargs)
93+
94+
if isinstance(result, tuple):
95+
data, (edgesx, edgesy) = result
96+
return data, edgesx, edgesy
97+
else:
98+
return result
9399

94100

95101
@_inject_signature(
@@ -110,7 +116,13 @@ def histogram(
110116
"Upgrade numpy to 1.13+ to use string arguments to boost-histogram's histogram function"
111117
)
112118
bins = np.histogram_bin_edges(a, bins, range, weights)
113-
return histogramdd((a,), (bins,), (range,), normed, weights, density, **kwargs)
119+
120+
result = histogramdd((a,), (bins,), (range,), normed, weights, density, **kwargs)
121+
if isinstance(result, tuple):
122+
data, (edges,) = result
123+
return data, edges
124+
else:
125+
return result
114126

115127

116128
# Process docstrings

tests/test_internal_histogram.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,25 @@ def test_growing_histogram():
117117
assert hist.size == 17
118118

119119

120+
def test_numpy_dd():
121+
h = bh.Histogram(
122+
bh.axis.Regular(10, 0, 1), bh.axis.Regular(5, 0, 1), storage=bh.storage.Int64()
123+
)
124+
125+
for i in range(10):
126+
for j in range(5):
127+
x, y = h.axes[0].centers[i], h.axes[1].centers[j]
128+
v = i + j * 10 + 1
129+
h.fill([x] * v, [y] * v)
130+
131+
h2, x2, y2 = h.to_numpy()
132+
h1, (x1, y1) = h.to_numpy(dd=True)
133+
134+
assert_array_equal(h1, h2)
135+
assert_array_equal(x1, x2)
136+
assert_array_equal(y1, y2)
137+
138+
120139
def test_numpy_flow():
121140
h = bh.Histogram(
122141
bh.axis.Regular(10, 0, 1), bh.axis.Regular(5, 0, 1), storage=bh.storage.Int64()

tests/test_numpy_interface.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,44 @@ def test_histogram2d_object():
116116
np.testing.assert_array_equal(h1, h2)
117117

118118
with pytest.raises(KeyError):
119-
bh_h2 = bh.numpy.histogram2d(x, y, density=True, histogram=bh.Histogram)
119+
bh.numpy.histogram2d(x, y, density=True, histogram=bh.Histogram)
120+
121+
122+
def test_histogramdd():
123+
x = np.array([0.3, 0.3, 0.1, 0.8, 0.34, 0.03, 0.32, 0.65])
124+
y = np.array([0.4, 0.5, 0.22, 0.65, 0.32, 0.01, 0.23, 1.98])
125+
z = np.array([0.5, 0.7, 0.0, 0.65, 0.72, 0.01, 0.3, 1.4])
126+
127+
h1, (e1x, e1y, e1z) = np.histogramdd([x, y, z])
128+
h2, (e2x, e2y, e2z) = bh.numpy.histogramdd([x, y, z])
129+
130+
np.testing.assert_array_almost_equal(e1x, e2x)
131+
np.testing.assert_array_almost_equal(e1y, e2y)
132+
np.testing.assert_array_almost_equal(e1z, e2z)
133+
np.testing.assert_array_equal(h1, h2)
134+
135+
h1, (e1x, e1y, e1z) = np.histogramdd([x, y, z], density=True)
136+
h2, (e2x, e2y, e2z) = bh.numpy.histogramdd([x, y, z], density=True)
137+
138+
np.testing.assert_array_almost_equal(e1x, e2x)
139+
np.testing.assert_array_almost_equal(e1y, e2y)
140+
np.testing.assert_array_almost_equal(e1z, e2z)
141+
np.testing.assert_array_almost_equal(h1, h2)
142+
143+
144+
def test_histogramdd_object():
145+
x = np.array([0.3, 0.3, 0.1, 0.8, 0.34, 0.03, 0.32, 0.65])
146+
y = np.array([0.4, 0.5, 0.22, 0.65, 0.32, 0.01, 0.23, 1.98])
147+
z = np.array([0.5, 0.7, 0.0, 0.65, 0.72, 0.01, 0.3, 1.4])
148+
149+
h1, (e1x, e1y, e1z) = np.histogramdd([x, y, z])
150+
bh_h2 = bh.numpy.histogramdd([x, y, z], histogram=bh.Histogram)
151+
h2, (e2x, e2y, e2z) = bh_h2.to_numpy(dd=True)
152+
153+
np.testing.assert_array_almost_equal(e1x, e2x)
154+
np.testing.assert_array_almost_equal(e1y, e2y)
155+
np.testing.assert_array_almost_equal(e1z, e2z)
156+
np.testing.assert_array_equal(h1, h2)
157+
158+
with pytest.raises(KeyError):
159+
bh.numpy.histogramdd([x, y, z], density=True, histogram=bh.Histogram)

0 commit comments

Comments
 (0)