Lets say I have an array that looks like:
[true, true, false]
And I am passing an operator along with the array which may be AND, OR or XOR.
So I want to calculate the logical value of array based on the operator specified.
ex:
for the given array [true, true, false] and the operator AND
I should be able to perform in continuation for n number of elements in array
Steps: true AND true -> true, true AND false -> false
therefore the output should be false
the array can be an n number of boolean values.
The best and easiest way to do this is using reduce:
def logical_calculation(arr, op)
op=='AND' ? arr.reduce(:&) : op=='OR' ? arr.reduce(:|) : arr.reduce(:^)
end
and also the other way is might be using inject
OPS = { "AND" => :&, "OR" => :|, "XOR" => :^ }
def logical_calculation(array, op)
array.inject(&OPS[op])
end
Related
I have an array of arrays:
all_arrays = np.array([[True, True, True],
[True, True, False],
[True, True, True],
[False, False, False]])
and I need to remove all subarrays that contains "True" for all elements. In this case, it should remain only the 2nd one and the last one.
The result should look like this:
array([[ True, True, False],
[False, False, False]])
I solved the problem by converting the array to a dataframe, perform the changes and then convert the dataframe back to an array
# Convert array to dataframe
zz = pd.DataFrame(all_arrays, columns = ['Column_A','Column_B','Column_C'])
# replace "True" with np.NaN
zz = zz.replace(True, np.nan)
# delete rows with all NaN
zz.dropna(how = 'all', inplace = True)
# replace back np.Nan with True
zz = zz.replace(np.nan, True)
# Convert dataframe array
all_arrays_filtered = zz.values
all_arrays_filtered
but I guess probably it is simpler and faster to do it using arrays but I don't know how to do it
Thank you for any help.
Invert mask for test if all values per rows are Trues by numpy.all:
a = all_arrays[~all_arrays.all(axis=1)]
print (a)
[[ True True False]
[False False False]]
I've got my 3d array called Pop. I want find out how many times two different conditions are met, and they both work for me independently but I can't put the two together.
Pop[end, :, 1] .== 3
works ok, produces an integer vector of 1's and 0's which is correct. Also
Pop[end-1, :, 1] .== 4
works, again returns integer vector, however when I put the two together as:
count(Pop[end, :, 1] .== 3 && Pop[end-1, :, 1] .== 4)
I get this error:
ERROR: TypeError: non-boolean (BitArray{1}) used in boolean context
Which sort of helps, can see that the two numeric arrays can not be compared in a boolean way. What is wrong with my syntax to get the count of the number of times both of the conditions are met. Simple I know but I can't get it! Thx. J
&& is a short-circuiting boolean, which means that if the first term is true, the rest isn't evaluated (see documentation). It also means it's only for a singular booleans and it cannot be broadcasted over an array.
& is the bitwise AND operator (documentation), that you want to use here, because it can be broadcasted over arrays with the syntax .&, the same way you use .==
julia> [true, true, false, false] .& [true, false, true, false]
4-element BitVector:
1
0
0
0
Update
in Julia 1.7+, the short-circuiting operators && and || can now be dotted to participate in broadcast fusion as .&& and .|| (#39594):
julia> [true, true, false, false] .&& [true, false, true, false]
4-element BitVector:
1
0
0
0
I need to filter an array by some condition on its elements, but I need to obtain the indices of the elements that passed the test, not the elements themselves.
For example: given an array of Bool, I want to transform that into an array of Int that contains only the indices of the elements of the orginal array that are true.
I could do this:
// INPUT array:
let flags = [true, false, true, false]
// OUTPUT array:
var trueIndices = [Int]()
for (index, value) in flags.enumerated() where value == true {
trueIndices.append(index)
}
...but it isn't "swifty" at all.
Is there a more elegant way? Something akin to filter(), but that returns the indices instead of the elements.
You can directly filter the indices
let flags = [true, false, true, false]
let trueIndices = flags.indices.filter{ flags[$0] }
and
let falseIndices = flags.indices.filter{ !flags[$0] }
Not sure how much "swiftier" it is, but you can also use a consecutive filter and map operation or just a single flatMap instead. For sure, you can declare the array immutable and you don't have to write any explicit loops, both of which are usually considered a more functional approach than your current one.
let trueIndices = flags.enumerated().filter{$0.element}.map{$0.offset}
print(trueIndices)
Output:
[0,2]
Using a single flatMap:
let trueIndices = flags.enumerated().flatMap { (offset, flag) in flag ? offset : nil }
Here's what I would do. It's generalizable to sequences, or even collections whose subscripting isn't O(1).
let indicesOfTrue = Array(flags.enumerated().lazy.filter{ $0.element }.map{ $0.offset })
I'm using Rails 5 and Ruby 2.4. If I have an array of strings, how do I figure out if there are two consecutive strings that match a regular expression?
For instance, I have:
["1234", "aa", "cc33", "44"]
I want to see if there are two consecutive elements that begin with letters (in the above case, that condition is true, "aa" and "cc33"). But in the below case it would be false:
["bb", "55", "mm", "77"]
This
my_arr.select { |str| str =~ /^\p{L}/ }
tells me how many strings begin with letters, but it doesn't tell me if I have two consecutive elements that begin with letters.
How do I figure that out?
Using your same regex, you could do this:
my_arr.each_cons(2).any? { |pair| pair.all? { |elem| elem =~ /^\p{L}/ } }
Check this snippet.
I understand you wish to determine if two consecutive elements of an array match a given regular expression. To do that efficiently we would like check as few elements (strings) as possible for matches. In particular, we don't want to necessarily check all elements of the array or check individual elements twice. Here is one way to do that.
arr = ["1234", "aa", "cc33", "44"]
r = /\A[[:alpha:]]{2}/
a = [false, false]
arr.any? do |s|
a[0] = s.match?(r)
a.rotate! == [true, true]
end
#=> true
String#match? made its debut in Ruby v2.4. For earlier versions one could write !!(s =~ r). The inner exclamation mark convert a truthy value to false and a falsy value to true; the outer exclamation mark flips that result from true to false and vice-versa.
I can easily fill part of an array using a logical array filter. ie the following works for an array:
mydata=[2 2 2];
myfilter=[false true true true false false];
myarray(myfilter)=mydata;
I tried the following for a struct array but it gives an error.
mydata=[2 2 2];
myfilter=[false true true true false false];
[mystruct(myfilter).myval] = mydata;
If I have already filled my struct array using a loop I can access the data with the same filter as follows:
mydata=[2 2 2];
myfilter=[false true true true false false];
pp=0;
for p=1:length(myfilter)
if myfilter(p)
pp=pp+1;
mystruct(p).myval = mydata(pp);
end
end
[mystruct(myfilter).myval]
So I can make a loop work to load the data then retrieve the data as expected, but is there a vectorised way to fill part of a struct array?
You may proceed as follows:
mydata=[2 2 2];
myfilter=[false true true true false false];
myarray(myfilter) = mydata ;
% make structure
mystruct = struct('myval', num2cell(myarray));