How to use logical indexing on multiple criteria [duplicate] - matlab

This question already has answers here:
Function for 'does matrix contain value X?'
(4 answers)
Closed 5 years ago.
I have a table that has a column containing values between 1 and 20. I want to filter the table such that I can show only certain discrete values, i.e. 3, 10, 12, and 19. The problem is writing this is cumbersome, especially since I want to write other criteria for filtering too.:
i = tb.subn==3 | tb.subn==10 | tb.subn==12 | tb.subn==19
If I use i = tb.subn==[3 10 12 19] then I get a :x4 boolean matrix. How can I get that into just one column?
If it were &, I suppose I could use prod(tb.subn==[3 10 12 19],2) but I can't figure out or.
Thanks.

You can use ismember(tb.subn, [3, 10, 12, 19])

i = all(tb.subn==[3 10 12 19], 2);
Note that this works only for very late matlab, while you solution will work better for all versions.

Related

Remove specific integers from matrix [duplicate]

This question already has answers here:
Exclude elements from array [duplicate]
(3 answers)
Closed 6 years ago.
I have a matrix <1x1000> containing integers. It contain the value 150 a couple of times and I want to remove that value completely. Any ideas how to?
Help is much appreciated!
If you want to remove all elements that equal 150 then
M = M(M ~= 150)
If you want to remove all elements belonging to a list of undesired numbers then
list = [150, 230, 420]
M = M(~ismember(M, list))
Same but different expression
M(M==150)=[];
list = [150,230,420];
M(ismember(M,list))=[];
When you type A(index)=[], it delete A(index). For example,
A = [1,2,3];
A(2) = [];
Then
A = [1,3]

Matlab increment bug? [duplicate]

This question already has answers here:
Matlab gives wrong answer
(3 answers)
Closed 8 years ago.
I don't know what's going on but when I use i = 0.1:0.1:7 in my code I get the integers 1 and 2, it then skips 3 but gets 4, 5, 6 and 7 no problems.
x=zeros((t_f/h)+1,1);
x(1,1)=0;
table=zeros(t_f,1);
for i=0.1:0.1:7;
x(round(i/h)+1,1)=i;
if ~mod(i,1)
table(i,1)=i;
end
end
Then to test I returned these
table
a=[x(1) x(11) x(21) x(41) x(51) x(61) x(71)]
a=[x(1) x(11) x(21) x(31) x(41) x(51) x(61) x(71)]
It's not finding 3 as an integer because i never is 3, it's 3.000... but 1, 2, 4, 5, 6 and 7 are integers.
It a floating point number representation issue. When the numbers are constructed in this way, the number you expect to be exactly 3 is off by a small amount (4.440892e-16). This is expected behaviour, not a bug, see: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

Select One Element in Each Row of a Numpy Array by Column Indices [duplicate]

This question already has answers here:
NumPy selecting specific column index per row by using a list of indexes
(7 answers)
Closed 2 years ago.
Is there a better way to get the "output_array" from the "input_array" and "select_id" ?
Can we get rid of range( input_array.shape[0] ) ?
>>> input_array = numpy.array( [ [3,14], [12, 5], [75, 50] ] )
>>> select_id = [0, 1, 1]
>>> print input_array
[[ 3 14]
[12 5]
[75 50]]
>>> output_array = input_array[ range( input_array.shape[0] ), select_id ]
>>> print output_array
[ 3 5 50]
You can choose from given array using numpy.choose which constructs an array from an index array (in your case select_id) and a set of arrays (in your case input_array) to choose from. However you may first need to transpose input_array to match dimensions. The following shows a small example:
In [101]: input_array
Out[101]:
array([[ 3, 14],
[12, 5],
[75, 50]])
In [102]: input_array.shape
Out[102]: (3, 2)
In [103]: select_id
Out[103]: [0, 1, 1]
In [104]: output_array = np.choose(select_id, input_array.T)
In [105]: output_array
Out[105]: array([ 3, 5, 50])
(because I can't post this as a comment on the accepted answer)
Note that numpy.choose only works if you have 32 or fewer choices (in this case, the dimension of your array along which you're indexing must be of size 32 or smaller). Additionally, the documentation for numpy.choose says
To reduce the chance of misinterpretation, even though the following "abuse" is nominally supported, choices should neither be, nor be thought of as, a single array, i.e., the outermost sequence-like container should be either a list or a tuple.
The OP asks:
Is there a better way to get the output_array from the input_array and select_id?
I would say, the way you originally suggested seems the best out of those presented here. It is easy to understand, scales to large arrays, and is efficient.
Can we get rid of range(input_array.shape[0])?
Yes, as shown by other answers, but the accepted one doesn't work in general so well as what the OP already suggests doing.
I think enumerate is handy.
[input_array[enum, item] for enum, item in enumerate(select_id)]
How about:
[input_array[x,y] for x,y in zip(range(len(input_array[:,0])),select_id)]

Matlab, how to convert a string of integers into a vector? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
convert string to number array in matlab
Is there a simple way in Matlab to convert a string like this
'123456789'
into a vector like this ?
[1 2 3 4 5 6 7 8 9]
If all you have is contiguous characters from 0 to 9:
v = double(s)-'0';
double(s) converts a string into an array where each element is the ASCII code of the corresponding character. To obtain the numberic values we subtract '0' (which is in fact 48 in ASCII) and since digits have a sequential representation in ASCII code ('1' = 49, '2' = 50, etc.) we end up with intended result.
one way would be using regexp for this. But of course it only works for single digit numbers.
>> str = '123456789';
>> num = regexp(str,'\d')
num =
1 2 3 4 5 6 7 8 9

Arrange data using loop in MATLAB

If I have:
t=(1:1:5)'
time=1:3:100
How do I arrange data t in each column starting from 1 until the end, with an interval of 3. Which means that the data t (1 to 5) at column 1,4,7 and so on.
I've tried:
t=[1:1:5];
nt=length(temp);
time=[1:1:100];
nti=length(time);
x=zeros(nt,nti);
temp=temp';
initiator=2;
monomer=3;
post=1:3:100;
for l=1:post
step=1;
maxstep=100;
while (step<maxstep)
step=step+3;
temp=(1:1:5)';
end
t(:,l)=t;
x=[t];
end
This only shows result X with temp at column 1. I do not know how to to arrange this data at columns that I want.
Hope someone will help me. Thank you in advance.
How many dimensions does your data have? If you already have "temp" (temperature?) and "time" as your first two dimensions and you want "t" to be the third dimension, then create a three-dimension matrix.
To extract from indexes [1 4 7 10 13 16 ... ], use (1:3:end)
To extract from indexed [2 5 8 11 14 17 ... ], use (2:3:end)
In MATLAB's colon notation, the first value is the start. Second value is increment. Third value is the end value and is inclusive.