Numpy ValueError broadcasting list of tuples into an array - python

I'm observing some odd behaviour using numpy broadcasting. The problem is illustrated below, where running the first piece of code produces an error:
A = np.ones((10))
B = np.ones((10, 4))
C = np.ones((10))
np.asarray([A, B, C])
ValueError: could not broadcast input array from shape (10,4) into shape (10)
If I instead expand the dimensions of B, using B = np.expand_dims(B, axis=0), it will successfully create the array, but it now has (not surprisingly) the wrong dimensions:
array([array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),
array([[[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]]]),
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])], dtype=float32)
Why does it fail to broadcast the first example, and how can I end up with an array like below (notice only double brackets around the second array)? Any feedback is much appreciated.
array([array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),
array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]]),
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])], dtype=object)

Including, say, None prevents the broadcasting, so this workaround is an option:
np.asarray([A, B, C, None])[:-1]
Here the outcome:
array([array([ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),
array([[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.]]),
array([ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])], dtype=object)

Related

Why does my image convert to a tensor with only ones?

I am using the GTZAN dataset (containing 1000 songs with 10 genres) to make a music genre classification project.
I tried to convert a dataset of images, which are spectrograms of the songs, into tensors but it only returns a tensor of ones.
This is how I tried to do it:
transform = T.Compose([
T.Resize(image_size),
T.ToTensor()
])
data = torchvision.datasets.ImageFolder(root = root, transform = transform)
train_loader = DataLoader(train_dataset,
batch_size=batch_size,
shuffle=True)
test_loader = DataLoader(test_dataset,
batch_size*2)
dataiter = iter(train_loader)
images, labels = dataiter.next()
When I return images it gives a tensor of pure ones, e.g.
images[1]
tensor([[[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.],
...,
[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.]],
[[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.],
...,
[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.]],
[[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.],
...,
[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.]]])
Are you sure it is all ones? Try to compute maximum/minimum/mean.
If that's the case, maybe you are reading the files assuming the wrong format.
This notebook could be of help https://www.kaggle.com/code/mireiaboneta/cnnmodel

What is the dimension of the difference of two vectors in python?

I tried to find the difference between two vectors on python colab. It returns a square matrix with the dimension being the number of rows of the vectors. As in np.subtract(y,X#genet).shape where y.shape returns (60,) and X#genet returns (60,). It is expected that np.subtract(y,X#genet).shape should return (60,) but it returned (60,60).
You sure your shapes are correct? if they are the same size then the resulting size would be the same.
>>> import numpy as np
>>> y = np.ones(60)
>>> y
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1.])
>>> y.shape
(60,)
>>> x = np.ones(60)
>>> x.shape
(60,)
>>> np.subtract(y, x).shape
(60,)
compute
It appears one of your arrays are the wrong shape (ie)
>>> y = np.ones(60)
>>> x = np.ones((60,1))
>>> np.subtract(y, x).shape
(60, 60)

change space between ticks in first y-axis in plt.imshow

Hey I have used the following code:
import matplotlib.pyplot as plt
import numpy as np
Class1=np.array([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 0., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [0., 0., 1., 0., 0., 0., 1., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [1., 1., 1., 0., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 0., 1., 0., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [0., 0., 0., 0., 0., 0., 1., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [1., 1., 1., 1., 1., 1., 1., 1., 0., 1., 1., 1., 0., 1., 0., 1., 0., 1.], [0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 1., 1., 1., 0.]])
Unique=np.array([ 0., 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.])
counts=np.array([56184982, 2904400, 4950837, 114746, 4270, 182052,
844444, 106292, 47007, 68480, 23522, 13838,
23990, 301704, 50462, 21345, 12263, 7217,
64194, 251, 885, 2947045, 4895643, 102992,
4401, 180136, 844872, 281, 107200, 48703,
69791, 22651, 50295, 22772, 7020, 62543,
43, 1103, 48])
list_y2=[]
list_x=[]
list_y1=[]
for i in np.arange(len(Unique)):
list_y2.append( np.array2string(round(counts[i]/Class1.sum(axis=1)[i],2)))
if i < 9:
list_x.append(str(i+1))
else:
list_x.append( str(i+1))
list_y1.append( str(38-int(Unique[i])))
fig, ax1 = plt.subplots()
F=16
ax1.set_xlabel('Brain image',fontsize=F)
ax1.set_yticks(np.arange(len(list_y1)))
ax1.set_yticklabels(list_y1)
ax1.set_xticks(np.arange(len(list_x)))
ax1.set_xticklabels(list_x)
ax1.set_ylabel('class',fontsize=F)
ax2 = ax1.twinx()
ax2.set_yticks(np.arange(len(list_y2)))
ax2.set_yticklabels(list_y2, va='baseline')
ax2.set_ylabel('size',fontsize=F)
#Rotate the tick labels and set their alignment.
plt.setp(ax1.get_xticklabels(), rotation=45, ha="right",
rotation_mode="anchor")
plt.imshow(Class1, aspect='auto')
fig.tight_layout()
plt.show()
which makes the following plot:
The problem with this is that the first y-axis doesn't fit the plot properly. The length between the ticks in the first y-axis should be the same as in the second y-axis and the 0 in the top and the 38 in bottom should be moved a bit inward on the y-axis. Hope one of you can help me.
I had the same problem recently and found the following workaround: Setting the same limits for the twin axis ax2 as for the parent axis (ax1). This aligns the ticks on both y-axes and then you proceed by setting the ticks and the labels as desired as you are doing.
ax2 = ax1.twinx()
ax2.set_ylim(ax1.get_ylim()) # This was the fix for me
ax2.set_yticks(np.arange(len(list_y2)))
ax2.set_yticklabels(list_y2, va='baseline')
ax2.set_ylabel('size',fontsize=F)
Let me know if it works.

cluster_selection_method error in dbscan

I am experimenting with clustering using the hdbscan package (0.8.3) in Python. Reading through the documentation leads me to want to test the different settings for cluster_selection_method (notably, setting it to 'leaf'). When I try to make this change I get:
__init__() got an unexpected keyword argument 'cluster_selection_method'
Here is how I call it:
clusterer = hdbscan.HDBSCAN(algorithm=algorithm,alpha=alpha,metric=metric,min_cluster_size=min_cluster_size \
,min_samples=min_samples,p=p,cluster_selection_method='leaf')
clusterer.fit(data['values'])
In this case data['values'] are all 1D arrays with each element having a value of 1.0 or 10.0 as shown below. Any advice on what might be preventing me from setting the cluster_selection_method would be appreciated.
array([ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 10., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
10., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 10.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 10., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 10., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 10., 1., 10., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 10., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
10., 10., 10., 10., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 10., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 10., 1., 1., 10., 10., 10.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 10., 10.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 10., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 10., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1.])
You may want to upgrade to a newer release of hdbscan; the cluster_selection_method was a relatively new addition.

How to plot the outlines of specific squares within a 2D grid using pcolormesh?

I have a (21 x 25) 2D array which contains two discrete values, "1" & "2".
The values are shown below:
value = np.array(
[[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 2., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 2., 2., 2.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 2., 1., 2., 2.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 2., 1., 2., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]])
If I plot this using pcolor, the resulting figure looks like this:
I want to draw the outlines of the grid squares where value == 2:
xx,yy = np.linspace(0,26,25),np.linspace(0,22,22)
xx,yy = np.meshgrid(xx,yy)
plt.pcolormesh(xx, yy, value, facecolor='none', edgecolor='b', alpha=0.8, zorder=2)
It seems like the outline isn't uniform (the lines have different shades), and I can't set the grid line colors by changing edgecolor.
You can render the squares where value == 1 as transparent by creating an np.ma.masked_array from value:
c = np.ma.masked_array(value, value == 1.) # mask squares where value == 1
plt.pcolormesh(xx, yy, c, alpha=0.8, zorder=2, facecolor='none', edgecolors='k',
cmap='gray')
Setting the colormap to 'gray' is a bit of a hack - unfortunately it seems that the default colormap overrides the edge color, even if you try to set it explicitly using edgecolor= or edgecolors=. I'm not sure whether or not this should be considered a bug in matplotlib.

Categories