Confused about numpy array operations - python-3.x

How come this be right?
X=np.array([range(1,12)])
A=X>4
B=X<10
C=(X>4) | (X<10)
print (X[A])
print (X[B])
print (X[C])
[ 5 6 7 8 9 10 11]
[1 2 3 4 5 6 7 8 9]
[ 1 2 3 4 5 6 7 8 9 10 11]

I'm going to guess that your concern is because you have every element in the final expression, simply because the first two are obvious (5..11 are all greater than four and 1..9 are all less than ten).
But the third one is also right since every element is either greater than four or less than ten. The numbers 1..9 are all less than ten so they're in. Similarly, 5..11 are all greater than four so they're in as well. The union of those two ranges is the entire set of values.
If you wanted the items that were between four and ten (exclusive at both ends), you should probably have used "and" instead of "or" (& instead of |):
import numpy as np
X=np.array([range(1,12)])
A=X>4
B=X<10
C=(X>4) | (X<10)
D=(X>4) & (X<10)
E=(X<=4) | (X>=10)
print (X[A])
print (X[B])
print (X[C])
print (X[D])
print (X[E])
The output of that is:
[ 5 6 7 8 9 10 11]
[1 2 3 4 5 6 7 8 9]
[ 1 2 3 4 5 6 7 8 9 10 11]
[5 6 7 8 9]
[ 1 2 3 4 10 11]
Because you didn't specify what you wanted in the original question), I've also added the opposite operation (to get values not in that range). That's indicated by the E code.

Related

How to generate an nd-array where values are greater than 1? [duplicate]

This question already has answers here:
Generate random array of floats between a range
(10 answers)
Closed 2 years ago.
Is it possible to generate random numbers in an nd-array such the elements in the array are between 1 and 2 (The interval should be between 1 and some number greater than 1 )? This is what I did.
input_array = np.random.rand(3,10,10)
But the values in the nd-array are between 0 and 1.
Please let me know if that is possible. Any help and suggestions will be highly appreciated.
You can try scaling:
min_val, max_val = 1, 2
input_array = np.random.rand(3,10,10) * (mal_val-min_val) + min_val
or use uniform:
input_array = np.random.uniform(min_val, max_val, (3,10,10))
You can use np.random.randInt() in order to generate nd array with random integers
import numpy as np
rand_arr=np.random.randint(low = 1, high = 10, size = (10,10))
print(rand_arr)
# It changes randomly
#Output:
[[6 9 3 4 9 2 6 2 9 7]
[7 1 7 1 6 2 4 1 8 6]
[9 5 8 3 5 9 9 7 8 4]
[7 3 6 9 9 4 7 2 8 5]
[7 7 7 4 6 6 6 7 2 5]
[3 3 8 5 8 3 4 5 4 3]
[7 8 9 3 5 8 3 5 7 9]
[3 9 7 1 3 6 3 1 4 6]
[2 9 3 9 3 6 8 2 4 8]
[6 3 9 4 9 5 5 6 3 7]]

Compare two matrices and create a matrix of their common values [duplicate]

This question already has an answer here:
Numpy intersect1d with array with matrix as elements
(1 answer)
Closed 5 years ago.
I'm currently trying to compare two matrices and return matching rows into the "intersection matrix" via python. Both matrices are numerical data-and I'm trying to return the rows of their common entries (I have also tried just creating a matrix with matching positional entries along the first column and then creating an accompanying tuple). These matrices are not necessarily the same in dimensionality.
Let's say I have two matrices of matching column length but arbitrary (can be very large and different row length)
23 3 4 5 23 3 4 5
12 6 7 8 45 7 8 9
45 7 8 9 34 5 6 7
67 4 5 6 3 5 6 7
I'd like to create a matrix with the "intersection" being for this low dimensional example
23 3 4 5
45 7 8 9
perhaps it looks like this though:
1 2 3 4 2 4 6 7
2 4 6 7 4 10 6 9
4 6 7 8 5 6 7 8
5 6 7 8
in which case we only want:
2 4 6 7
5 6 7 8
I've tried things of this nature:
def compare(x):
# This is a matrix I created with another function-purely numerical data of arbitrary size with fixed column length D
y =n_c(data_cleaner(x))
# this is a second matrix that i'd like to compare it to. note that the sizes are probably not the same, but the columns length are
z=data_cleaner(x)
# I initialized an array that would hold the matching values
compare=[]
# create nested for loop that will check a single index in one matrix over all entries in the second matrix over iteration
for i in range(len(y)):
for j in range(len(z)):
if y[0][i] == z[0][i]:
# I want the row or the n tuple (shown here) of those columns with the matching first indexes as shown above
c_vec = ([0][i],[15][i],[24][i],[0][25],[0][26])
compare.append(c_vec)
else:
pass
return compare
compare(c_i_w)
Sadly, I'm running into some errors. Specifically it seems that I'm telling python to improperly reference values.
Consider the arrays a and b
a = np.array([
[23, 3, 4, 5],
[12, 6, 7, 8],
[45, 7, 8, 9],
[67, 4, 5, 6]
])
b = np.array([
[23, 3, 4, 5],
[45, 7, 8, 9],
[34, 5, 6, 7],
[ 3, 5, 6, 7]
])
print(a)
[[23 3 4 5]
[12 6 7 8]
[45 7 8 9]
[67 4 5 6]]
print(b)
[[23 3 4 5]
[45 7 8 9]
[34 5 6 7]
[ 3 5 6 7]]
Then we can broadcast and get an array of equal rows with
x = (a[:, None] == b).all(-1)
print(x)
[[ True False False False]
[False False False False]
[False True False False]
[False False False False]]
Using np.where we can identify the indices
i, j = np.where(x)
Show which rows of a
print(a[i])
[[23 3 4 5]
[45 7 8 9]]
And which rows of b
print(b[j])
[[23 3 4 5]
[45 7 8 9]]
They are the same! That's good. That's what we wanted.
We can put the results into a pandas dataframe with a MultiIndex with row number from a in the first level and row number from b in the second level.
pd.DataFrame(a[i], [i, j])
0 1 2 3
0 0 23 3 4 5
2 1 45 7 8 9

I want to export my Data in a Cell Array to an Excel file, as tidy as possible, without semi-colons for new rows

I have a Cell Array of dimensions 2 by 40, and each cell contains a matrix of dimensions 3 by 3:
[3x3 double] [3x3 double] [3x3 double] ... [3x3 double]
[3x3 double] [3x3 double] [3x3 double] ... [3x3 double]
Now, I need to print this Cell Array and show it to my study group. Below is the detailed example of what I am trying to achieve.
Print should show each matrix in the cell clearly and separately, so that we can study it better, similar to this:
[1 2 3] [5 2 3]
[4 5 6] [1 2 2] ...
[7 8 9] [7 8 9]
[5 2 3] [4 5 6]
[3 5 6] [7 2 9] ...
[7 1 9] [5 2 3]
I tried converting Cell to Table, unfortunately this was untidy, as it showed each new row of matrices with semi-colons:
[1 2 3; 4 5 6; 7 8 9]
Also, I tried converting Cell to Double with:
data = [cell{1,:};cell{2,:}];
resulting in 6 by 120 double, looking like this:
1 2 3 5 2 3
4 5 6 1 2 2 ...
7 8 9 7 8 9
5 2 3 2 5 6
3 5 6 7 2 9 ...
7 1 9 5 2 3
I can export this to an Excel file, however you can see that it is still cumbersome. I can cut and paste the rows 4,5,6 and shift them below so that it looks like:
1 2 3 5 2 3
4 5 6 1 2 2 ...
7 8 9 7 8 9
5 2 3 2 5 6
3 5 6 7 2 9 ...
7 1 9 5 2 3
however I still need to divide every other 3 columns, so that I can achieve what I want, which is very impractical:
1 2 3 5 2 3
4 5 6 1 2 2 ...
7 8 9 7 8 9
5 2 3 2 5 6
3 5 6 7 2 9 ...
7 1 9 5 2 3
I would really appreciate your help on this one. Thank you in advance.
To display a complex cell array like this, you can use celldisp to display the cell in an understandable way.
% Create some example data
D = arrayfun(#(x)rand(3,3), ones(2,2), 'uni', 0);
% Display it
celldisp(D)
Another possible way to display this is to create a custom little routine to print the data.
formatspec = '%10.4f';
format = repmat([repmat([formatspec ' '], [1 size(D{1},2)]), ' '], [1 size(D,2)]);
arrayfun(#(k)fprintf('%s\n', sprintf([format, '\n'], cat(2, D{k,:}).')), 1:size(D,1))
A third option, if you really want to export to Excel, you will want to alter the fprintf statement to create a CSV file.
fid = fopen('data.csv', 'w');
% Create the format specifier for a row
format = repmat([repmat('%0.4f,', [1 size(D{1}, 2)]), ','], [1 size(D,2)]);
format(end-1:end) = '';
for k = 1:size(D, 1)
fprintf(fid, [format '\n'], cat(2, D{k,:}).');
% Create an empty row
fprintf(fid, ',\n');
end
fclose(fid);
The result when loaded in Excel.

How change an arbitrary range of values to ranged values?

I am going to convert an array as [1 2 6 12 13 15 20 8 30 31] to range [1 2 3 4 5 6 7 8 9 10] in EXCEL or in MATLAB. Is there any function to do it? Is there any suggestion to convert this type of arbitrary range to definite range?
Solution for MATLAB
In MATLAB, unique can do the trick. For example:
A = [1 1 1 1 4 4 5 3 3 6 6 6 6 8]
[C, ia, ic] = unique(A);
Now ic holds the values that you're looking for:
ic =
1 1 1 1 3 3 4 2 2 5 5 5 5 6
Also, you can remap ic to a new order if you wish to do so. For instance, here's a new order similar to the one you suggested:
new_order = [1 3 2 4 6 5];
ic_new = new_order(ic);
which yields:
ic_new =
1 1 1 1 2 2 4 3 3 6 6 6 6 5
Hope that helps!
In Matlab:
v = [1 2 6 12 13 15 20 8 30 31];
v_index = 1:length(v);

How to generate all possible combinations of values from n different sets?

I have n sets, each having n1,n2,n3...nN distinct members.
How do I generate n1*n2*n3...*nN possible combinations from them
e.g
[6] [4 5] [1 2 3 4]
will give
6 4 1
6 4 2
6 4 3
6 4 4
6 5 1
6 5 2
6 5 3
6 5 4
I want to do this in matlab, but a normal algorithm would also be fine
An easy solution is to simulate a sum !
Start with a list of indices 0 0 0, corresponding to the indices of your values. That leads you to the value 6 4 1 in your example.
then add 1.
You now have indices 001, so 642
and so on.
at 004, you overflow, so your indices become 010, having 6 5 1
Keep doing that, and keep a counter of the visited possibilites. There are 1 * 2 * 4 possibilities, so it's easy to know when you are done.
I think you're looking for Cartesian product of sets:
This should help:
cartprod(N1,N2,N3, ...)
http://www.mathworks.com/matlabcentral/fileexchange/5475-cartprod-cartesian-product-of-multiple-sets
There's another one here
set = {n1, n2, n3, ...}
allcomb(set{:})

Resources