Numpy equivalent to MATLAB's hist - matlab

For some reason Numpy's hist always returns one less bin than MATLAB's hist:
for example in MATLAB:
x = [1,2,2,2,1,4,4,2,3,3,3,3];
[Rep,Val] = hist(x,unique(x));
gives:
Rep = [2 4 4 2]
Val = [1 2 3 4]
but in Numpy:
import numpy as np
x = np.array([1,2,2,2,1,4,4,2,3,3,3,3])
Rep, Val = np.histogram(x,np.unique(x))
gives:
>>>Rep
array([2, 4, 6])
>>>Val
array([1, 2, 3, 4])
How can I get identical results ti MATLAB's?

Based on dilayapici's answer on this post, a general solution (applied to your example) to run Python's np.histogram in the same way as Matlab's hist, is the following:
x = np.array([1,2,2,2,1,4,4,2,3,3,3,3])
# Convert the bin centers given in Matlab to bin edges needed in Python.
numBins = len(np.unique(x))
bins = np.linspace(np.amin(x), np.amax(x), numBins)
# Edit the 'bins' argument of `np.histogram` by just putting '+inf' as the last element.
bins = np.concatenate((bins, [np.inf]))
Rep, Val = np.histogram(x, bins)
Output:
Rep
array([2, 4, 4, 2], dtype=int64)

Firstly I want to explain this problem.
In Phyton it is running like:
np.unique(x) = [1, 2, 3, 4] so,
The first bin is equal to [1, 2) (including 1, but excluding 2) and therefore ==> Rep[0]=2
The second bin is equal to [2, 3) (including 2, but excluding 3) and therefore ==> Rep[1]=4
The last bin is equal to [3, 4], which includes 4. Therefore ==> Rep[2] = 6
In MATLAB hist() function is running like:
The first bin is equal to [1, 2) (including 1, but excluding 2) and therefore ==> Rep[0]=2
The second bin is equal to [2, 3) (including 2, but excluding 3) and therefore ==> Rep[1]=4
The third bin is equal to [3, 4) (including 3, but excluding 4) and therefore ==> Rep[2]=4
The last bin is equal to [4, ∞) and therefore ==> Rep[3]=2
Now If you want same result in Pyhton, you have to use different function in Matlab. This is histogram() function. We can decide "bins number".
x = [1,2,2,2,1,4,4,2,3,3,3,3];
nbins=3 ;
h= histogram(x,nbins);
h.Values
You can see h.Values equals to [2,4,6].
I hope, I could help :)

Related

How can I find each max element of three matrices as new matrix?

Maybe the question is a little bit confused, I'll make an example below.
Let's say I have a 3 matrices a, b, c with same size.
a = [2, 5; 6, 9];
b = [3, 3; 8, 1];
c = [5, 5; 2, 7];
How can I get the new matrix max with each max element in all three matrices?
max = [5, 5; 8, 9]
I know I could create logical matrix like a>b and then do the math, calc it out, is there any other more efficient way to do it?
You can concatenate the matrices into one 2x2x3 matrix using
d=cat(3,a,b,c)
and then use max-function to get your desired output:
maxValues=max(d,[],3)
The 3rd input to max defines along which dimension of the first input you want to find the maximum value.

Matlab find the maximum and minimum value for each point of series of arrays (with negative values)

lets say that we have the next series of arrays:
A = [1, 2, -2, -24];
B = [1, 4, -7, -2];
C = [3, 1, -7, -14];
D = [11, 4, -7, -1];
E = [1, 2, -3, -4];
F = [5, 14, -17, -12];
I would like to create two arrays,
the first will be the maximum of each column for all arrays,
i.e.
Maxi = [11,14,-2 -1];
the second will be the minimum of each column for all arrays
i.e.
Mini= [1,1,-17 -24];
I am trying all day, using loops, with max, and abs but I cant make it work
in my problem have a matrix (100,200), so with the above example i am trying to easily approach the problem. The ultimate goal is to get a kinda fitting of the 100 y_lines of 200 x_points. The idea is to calculate two lines (i.e. max,min), that will be the "visual" boarders of all lines (maximum and minimum values for each x). The next step will be to calculate an array of the average of these two arrays, so in the end will be a line between all lines.
any help is more than welcome!
How about this?
Suppose you stack all the row vectors , namely A,B...,F as
arr=[A;B;C;D;E;F];% stack the vectors
And then use the max(), min() and mean() functions provided by Matlab. That is,
Maxi = max(arr); % Maxi is a row vector carrying the max of each column of arr
Mini = min(arr);
Meani = mean(arr);
You just have to stack them as shown above. But if you have 100s of row vectors, use a loop to stack them into array arr as shown above.

How to find all index pairs of unequal elements in vector (Matlab)

Lets say I have the following vector in Matlab:
V = [4, 5, 5, 7];
How can I list (in a n-by-2 matrix for example) all the index pairs corresponding to unequal elements in the vector. For example for this particular vector the index pairs would be:
index pairs (1, 2) and (1, 3) corresponding to element pair (4,5)
index pair (1, 4) corresponding to element pair (4,7)
index pairs (2, 4) and (3, 4) corresponding to element pair (5,7)
The reason I need this is because I have a cost-function which takes a vector such as V as input and produces a cost-value.
I want to see how does the random swapping of two differing elements in the vector affect the cost value (using this for steepest descent hill climbing).
The order of the index pairs doesn't also matter. For my purposes (1,2) is the same as (2,1).
For example if my cost-function was evalCost(), then I could have V = [4, 5, 5, 7] and
evalCost(V) = 14
whereas for W = [4, 7, 5, 5] the cost could be:
evalCost(W) = 10
How to get the list of "swapping" pair indexes in Matlab. Hope my question is clear =)
I don't understand the cost function part, but the first part is simple:
[a,b]=unique(V)
C = combnk(b,2)
C contains the indices, and V(C) the values:
C = combnk(b,2)
C =
1 2
1 4
2 4
V(C)
ans =
4 5
4 7
5 7
Use bsxfun and then the two-ouput version of find to get the pairs. triu is applied to the output of bsxfun to consider only one of the two possible orders.
[ii jj] = find(triu(bsxfun(#ne, V, V.')));
pairs = [ii jj];

Matlab: How to use 'bitxor' for more inputs than 2?

I hope someone can help me with this particular problem:
I need to calculate 'bitxor' for more than two inputs. I have a vector of intputs/elements where the number of inputs/elements varies. For instance, in case of a four elements Vector, the solution is as follows:
Vector: Y = [1 3 5 7];
Solution: bitxor(bitxor(Y(1),Y(2)),bitxor(Y(3),Y(4)));
Is there any way where I can write this in a more general way, such that I get one value/elemet no matter how many inputs elements there is in vector Y?
A 'back of the envelope' solution seems to be to convert each number in the list to binary and sum up the number of 1s in each bit column.
If the sum in a particular column number is even, then that column will hold a 0 in your final (binary) result, if it is odd, it will hold a 1.
So your example of bitxor([1 3 5 7]):
0001 (dec 1)
0011 (dec 3)
0101 (dec 5)
0111 (dec 7)
====
Bit-wise sum: 0224 (Not base 2 here, obviously)
Convert via even/odd rule above:
0224 => bin 0000 (or dec 0)
I tried it on a few quick examples offhand and didn't run into an exception.
So some code to try the solution out:
Y = [1, 3, 5, 7];
strMat = dec2bin(Y); % Convert Y to char matrix of binary values
for i = 1:size(strMat,2)
colSum = sum( str2num(strMat(:,i))); % Sum up each column
finalVal(i) = num2str( mod(colSum,2)); % Check whether column sum is even
end
finalVal = bin2dec(finalVal); % Convert solution to decimal
The solution I will describe now is far from being optimal, but you can give it a try anyway:
Y1 = Y(1:2:end);
Y2 = Y(2:2:end);
arrayfun(#(i) bitxor(bitxor(Y1(i),Y2(i)),bitxor(Y1(i),Y2(i))),1:size(Y1,1))
This is another solution , but it overwrites the original vector.
Y = [1, 3, 5, 7];
for i=1:length(Y)-1
Y(i+1) = bitxor(Y(i),Y(i+1));
end
finalVal = Y(end)

MATLAB addressing different matrix elments with an index?

How can I create an index-matrix that specifies which elements of a matrix to address?
So for example I have a matrix A which is 80 by 50. I know that A(1:5,:) addresses only the first 5 elements, but what if I want to multiply A with another matrix which also changes the elements to be addressed? So I want to multiply B(1,:) with A(1:5,:), and B(2,:) with A(10:15,:) and so on. Is there a smart way to specify this index-matrix where the information (1:5; 10:15, etc.) is stored?
Yes you can certainly define indices into a matrix using another matrix. Here is a simple example using a cell array to store the index list:
X =[1,2,3,4,5,6]
Idx = { [1, 2, 3], [4, 5, 6] }
Y = X( Idx{1} ) .* X( {Idx{2} )
Y = [ 4, 10, 18]