- 
      
- 
        Save isentropic/a86effab2c007e86912a50f995cac52b to your computer and use it in GitHub Desktop. 
| import tensorflow as tf | |
| @tf.function | |
| def get2dHistogram(x, y, | |
| value_range, | |
| nbins=100, | |
| dtype=tf.dtypes.int32): | |
| """ | |
| Bins x, y coordinates of points onto simple square 2d histogram | |
| Given the tensor x and y: | |
| x: x coordinates of points | |
| y: y coordinates of points | |
| this operation returns a rank 2 `Tensor` | |
| representing the indices of a histogram into which each element | |
| of `values` would be binned. The bins are equal width and | |
| determined by the arguments `value_range` and `nbins`. | |
| Args: | |
| x: Numeric `Tensor`. | |
| y: Numeric `Tensor`. | |
| value_range[0] lims for x | |
| value_range[1] lims for y | |
| nbins: Scalar `int32 Tensor`. Number of histogram bins. | |
| dtype: dtype for returned histogram. | |
| Example: | |
| N = 1000 | |
| xs = tf.random.normal([N]) | |
| ys = tf.random.normal([N]) | |
| get2dHistogram(xs, ys, ([-5.0, 5.0], [-5.0, 5.0]), 50) | |
| """ | |
| x_range = value_range[0] | |
| y_range = value_range[1] | |
| histy_bins = tf.histogram_fixed_width_bins(y, y_range, nbins=nbins, dtype=dtype) | |
| H = tf.map_fn(lambda i: tf.histogram_fixed_width(x[histy_bins == i], x_range, nbins=nbins), | |
| tf.range(nbins)) | |
| return H # Matrix! | 
How could I change the code to add a weight argument, such as in numpy implementation?
I have tried so far the following, but it does not return the correct values for the histogram:
`def get2dHistogram(x, y, weights,
value_range,
nbins=100,
dtype=tf.dtypes.int32):
x_range = value_range[0]
y_range = value_range[1]
x = tf.histogram_fixed_width_bins(x, y_range, nbins=tf.size(x), dtype=dtype)
x = tf.math.bincount(x, weights=weights, minlength=tf.size(y))
y = tf.histogram_fixed_width_bins(y, y_range, nbins=tf.size(y), dtype=dtype)
y = tf.math.bincount(y, weights=weights, minlength=tf.size(y))
histy_bins = tf.histogram_fixed_width_bins(y, y_range, nbins=nbins, dtype=dtype)
H = tf.map_fn(lambda i: tf.histogram_fixed_width(x[histy_bins == i], x_range, nbins=nbins), tf.range(nbins))
return H # Matrix!`
maybe you could multiply the resulting histogram with weights
...
edit: this wont work I get it.
Perhaps if weights aren't that important perhaps duplicate (add multiplicity) to some of the points manually?
I managed to make it work using the tensorflow-probability package for the histogram implementation. The final is below:
`def get2dHistogram(x, y, weights,
value_range,
nbins=100,
dtype=tf.dtypes.int32):
x_range = tf.linspace(value_range[0][0], value_range[0][1], num=nbins+1)
x = tf.clip_by_value(x, value_range[0][0], value_range[0][1])
histy_bins = tf.histogram_fixed_width_bins(y, value_range[1], nbins=nbins, dtype=dtype)
hists = []
for i in range(nbins):
_x = x[histy_bins == i]
_w = weights[histy_bins == i]
hist = tfp.stats.histogram(_x, edges=x_range, weights=_w)
hists.append(hist)
return tf.stack(hists, axis=0)`
I think TF version is irrelevant here, it works with
2.2as well