I have two cell arrays of strings as follows
A={{a,b},{c},{d,e}}
B={{a,b},{c,d},{e}}
I want to check if A is a subset of B, meaning that each cell in A has a super-cell in B. In the given example it is not since A contains {d,e} while B does not have any cell that has those or more elements.
I think ismember should be useful in this case, but I just could not write down the logic.
Thank you!
Given A and B
A={{'a','b'},{'c'},{'d','e'}}
B={{'a','b'},{'c','d'},{'e'}}
We can define a function isSubset, as follows:
isSubset = #(superSet,subSet)isempty(setdiff(subSet, superSet));
And test it:
isSubset(B{1}, A{1}) %true
isSubset(B{2}, A{2}) %true
isSubset(B{3}, A{3}) %false
Now we can use isSubSet and cellfun to define a function isSubSetOfAny, which checks to see if a particular subset is a subset of any of a set of sets, like this:
isSubSetOfAny = #(superSetSet, subSet) any(cellfun(#(x)isSubset(x, subSet), superSetSet));
And test it:
isSubSetOfAny(B, A{1}) %True
isSubSetOfAny(B, A{2}) %True
isSubSetOfAny(B, A{3}) %True
Now we can use isSubSetOfAny plus cellfun (again) to define isEachMemberASubsetOfAny, which performs the operation you describe:
isEachMemberASubsetOfAny = #(superSetSet, subSetSet) all(cellfun(#(x)isSubSetOfAny(superSetSet, x), subSetSet));
And test it:
isEachMemberASubsetOfAny(B, A) %Returns false
A_1 = {{'a','b'},{'c'},{'e'}}; %Define a variant of `A`
isEachMemberASubsetOfAny(B, A_1) %Returns false
How about something like:
function tf = is_subset(A,B)
narginchk(2,2)
assert(iscell(A) && all(cellfun(#iscellstr,A)));
assert(iscell(B) && all(cellfun(#iscellstr,B)));
for ia=1:numel(A)
tf = false;
for ib=1:numel(B)
if all(ismember(A{ia},B{ib}));
tf = true;
break
end
end
if ~tf
break
end
end
end
With
[a,b,c,d,e] = deal('1','2','3','4','5');
A = {{a,b},{c},{d,e}};
B = {{a,b},{c,d},{e}};
is_subset(A,B) %# false
B = {{a,b},{c,d,e},{e}};
is_subset(A,B) %# true
Assuming a,b etc are strings you could do the following:
For each cell of A loop through B and see whether there is a cell in B for which all elements in the cell are member. Here is an example:
A={{'abc','b'},{'c'},{'d','e'}};
B={{'aabc','b'},{'c','d'},{'d','e'}}; %Remove the first a to return true
subset = true;
for i = 1:length(A)
found = false;
for j = 1:length(B)
found = found || all(ismember(A{i},B{j}));
end
subset = subset && found;
end
subset
What are the types of a, b, etc.? If they are strings, you can use setdiff to test whether one set is contained within another. Suitable use of cellfun and any or all should do it. Like so:
all(cellfun(#(a)any(cellfun(#(b)isempty(setdiff(a,b)),B)),A))
If they're some other type, you can make a simple m-file to check for a super-cell. Replace isempty(setdiff(a,b)) with a call to this function. It will have to loop through the elements of a and check for each one whether it exists in b.
Related
I have a string :
A="ILOVEYOUMATLAB"
and I create 2 empty array:
B1=[]
B2=[]
when i used the while loop, for the first time looping, if i want the first character from the A to store in B1 array, what command i need to write?
if in Python, i just need to used append command, but if in Matlab, what is the commend need to apply?
If you have MATLAB R2016b or newer you can use the new string class' overloaded + operator to append text in a more pythonic manner:
A = 'hi';
B = "";
B = B + A(1)
Which gives you:
B =
"h"
Here I've created A as a traditional character array ('') and B as a string array (""), mainly to avoid having to index into the string array (A{1}(1) instead of A(1)).
You can also just use traditional matrix concatenation to accomplish the task:
B = [B, A(1)];
% or
B = strcat(B, A(1));
% or
B(end+1) = A(1);
Note that 4 of these approaches will continually grow B in memory, which can be a significant performance bottleneck. If you know how many elements B is going to contain you can save a lot of IO time by preallocating the array and using matrix indexing to assign values inside your loop:
A = {'apple', 'banana', 'cucumber'};
B = char(zeros(1, numel(A)));
for ii = 1:numel(A)
B(ii) = A{ii}(1);
end
you can try strcat for concatenating strings in matlab
https://www.mathworks.com/help/matlab/ref/strcat.html
Try using arrays instead of matrices. You can assign the first letter to the first position of the B1 array like this:
>> A = 'ILOVEMATLAB';
>> B1 = {};
>> B1{1} = A(1);
>> B1{1}
ans =
I
To Loop through:
for i = 1:length(A)
B1{i} = A{i};
end
I have a vector/ or it could be array :
A = [1,2,3,4,5,1,2,3,4,5,1,2,3]
I want to extract existing different values/elements from this vector without repeating:
1,2,3,4,5
B= [1,2,3,4,5]
How can I extract it ?
I would appreciate for any help please
Try this,
A = [1,2,3,4,5,1,2,3,4,5,1,2,3]
y = unique(A)
B = unique(A) returns the same values as in a but with no repetitions. The resulting vector is sorted in ascending order. A can be a cell array of strings.
B = unique(A,'stable') does the same as above, but without sorting.
B = unique(A,'rows') returns the unique rows ofA`.
[B,i,j] = unique(...) also returns index vectors i and j such that B = A(i) and A = B(j) (or B = A(i,:) and A = B(j,:)).
Reference: http://cens.ioc.ee/local/man/matlab/techdoc/ref/unique.html
Documentation: https://uk.mathworks.com/help/matlab/ref/unique.html
The answers below are correct but if the user does not want to sort the data, you can use unique with the parameter stable
A = [1,2,3,4,5,1,2,3,4,5,1,2,3]
B = unique(A,'stable')
Let's say I have an array of vectors:
""" simple line equation """
function getline(a::Array{Float64,1},b::Array{Float64,1})
line = Vector[]
for i=0:0.1:1
vector = (1-i)a+(i*b)
push!(line, vector)
end
return line
end
This function returns an array of vectors containing x-y positions
Vector[11]
> Float64[2]
> Float64[2]
> Float64[2]
> Float64[2]
.
.
.
Now I want to seprate all x and y coordinates of these vectors to plot them with plotyjs.
I have already tested some approaches with no success!
What is a correct way in Julia to achive this?
You can broadcast getindex:
xs = getindex.(vv, 1)
ys = getindex.(vv, 2)
Edit 3:
Alternatively, use list comprehensions:
xs = [v[1] for v in vv]
ys = [v[2] for v in vv]
Edit:
For performance reasons, you should use StaticArrays to represent 2D points. E.g.:
getline(a,b) = [(1-i)a+(i*b) for i=0:0.1:1]
p1 = SVector(1.,2.)
p2 = SVector(3.,4.)
vv = getline(p1,p2)
Broadcasting getindex and list comprehensions will still work, but you can also reinterpret the vector as a 2×11 matrix:
to_matrix{T<:SVector}(a::Vector{T}) = reinterpret(eltype(T), a, (size(T,1), length(a)))
m = to_matrix(vv)
Note that this does not copy the data. You can simply use m directly or define, e.g.,
xs = #view m[1,:]
ys = #view m[2,:]
Edit 2:
Btw., not restricting the type of the arguments of the getline function has many advantages and is preferred in general. The version above will work for any type that implements multiplication with a scalar and addition, e.g., a possible implementation of immutable Point ... end (making it fully generic will require a bit more work, though).
I want to create a 2D list that can have elements of variable lengths inside, for example, if I have a 10x10 list in MATLAB, I can
define it with:
z = cell(10,10)
and start assigning some elements by doing this:
z{2}{3} = ones(3,1)
z{1}{1} = zeros(100,1)
z{1}{2} = []
z{1}{3} = randn(20,1)
...
What is the optimal way to define such empty 2D list in torch? Moreover, is there a way to exploit the tensor structure to do this?
In python, I can do something along this to define an empty 10x10 2D list:
z = [[None for j in range(10)] for i in range(10)]
My best guess for torch is doing something like
z = torch.Tensor(10,10)
for i=1,10 do
for j=1,10 do
z[{{i},{j}}] = torch.Tensor()
end
end
but, this does not work, and defining a tensor inside a tensor seems like a bad idea ...
This is a follow up to the question asked here (however in the link it is asked in python): Create 2D lists in python with variable length indexed vectors
From the documentation I've read, tensors only support primitive numeric data types. You won't be able to use tensor for your intended usage. Leverage tables.
local function makeMatrix(initialVal, ...)
local isfunc = type(initialVal) == "function"
local dimtable = {...}
local function helper(depth)
if depth == 0 then
return isfunc and initialVal() or initialVal
else
local plane = {}
for i = 1, dimtable[depth] do
plane[i] = helper(depth-1)
end
return plane
end
end
return helper(#dimtable)
end
p = makeMatrix(0, 2, 3, 5) -- makes 3D matrix of size 2x3x5 with all elements initialized to 0
makeMatrix(torch.Tensor, m ,n)
Answer from Torch's Google Group forums. Agreeing that tables is the solution:
z = {}
for i=1,10 do
z[i] = {}
for j=1,10 do
z[i][j] = torch.Tensor()
end
end
I have three arrays of arrays like this:
catLabels = [catA, catB, catC]
binaryLabels = [binA, binB, binC]
trueLabels = []
trueLabels.extend(repeat(y_true_categories, len(binaryLabels)))
def binaryConversion(trueLabel, evalLabel, binaryLabel):
for true,eval, binary in zip(trueLabel, evalLabel, binaryLabel):
if eval == true:
binary.append(1)
else:
binary.append(0)
for x,y,z in zip(trueLabels,catLabels,binaryLabels):
binaryConversion(x, y, z)
Each of the values in catLabels and binLabels is an array. binLabels contain an array of empty arrays, each of which I want to fill in 1s and 0s lets say for example catA = [A B C A B D] and binA = []. trueLabels contains multiple arrays each of which are the same (y_true_categories, i.e. my true categorical labels [A C C B B D]. In this case, my binaryConversion function should fill in [1 0 1 0 1 1] for the array binA.
For some reason my current function is not achieving this and leaves each of bin A, binB, binC empty.
What am I doing wrong?
I have figured out the answer. The inner zip statement will not work because I start with empty binary labels, and zip only works when all the arrays you are zipping are of the same length. So I removed the binaryLabel from the zip function within binaryConversion(trueLabel, evalLabel, binaryLabel) and appended to each binaryLabel empty binary array inside the loop. In addition, I was appending 1s and 0s to the element-wise binary, instead of the actual empty array binaryLabel.
New code:
def binaryConversion(trueLabel, evalLabel, emptyBinaryArray):
for true,eval in zip(trueLabel, evalLabel):
if eval == true:
emptyBinaryArray.append(1)
else:
emptyBinaryArray.append(0)
for trueLabels,predictionLabels,emptyBinaryArray in zip(trueLabels,catLabels,binaryLabels):
binaryConversion(trueLabels, predictionLabels, emptyBinaryArray)