Count elements in an array - arrays

I have an array that contains string elements:
farm = np.array(garden)
leads to this:
[['F' 'F' 'W' 'W']
['F' '_' '_' 'W']
['G' '_' '_' 'J']
['G' 'G' 'J' 'J']]
I want to count how many times lets say 'F' appears, is there a simple way to do this? This is a small version of the bigger array that I will be working on

EDIT:
Lists have a count method. So your new and improved pythonic code is
D= sum([i.count("F") for i in listX])
Well you can make a function, that
Checks if the parameter passed to it is in the array. You can even use list comprehensions. For example
F = sum([sum([1 for i in j if i=="f"]) for j in listX])

Michael's solution is the most "pythonic", but I wanted to offer an alternative solution using simpler constructs, in case you're just learning:
lst = []
lst.append(['F', 'F', 'W', 'W'])
lst.append(['F', '_', '_', 'W'])
lst.append(['G', '_', '_', 'J'])
lst.append(['G', 'G', 'J', 'J'])
numFs = 0
# Look at each sublist
for sublist in lst:
# Look at each element within the sublist
for s in sublist:
# If the element is an 'F', add 1 to the number of Fs
if s == 'F':
numFs += 1
print(numFs)

You could also try to reduce and join the elements of the arrays into a string and then count, like so:
from functools import reduce
a = [['F' 'F' 'W' 'W'], ['F' '_' '_' 'W'], ['G' '_' '_' 'J'], ['G' 'G' 'J' 'J']]
c = ''.join(reduce(list.__add__, a)).count('F')
print(c)
When executed, this code prints:
3

Related

Is there an array method in Ruby for "must include at least one of these but can't include anything else"?

I'm doing an exercise where the input is an array. I need a way to return false if the array contains anything other than the strings 'n', 's', 'e' and 'w' or if the array does not contain any of the strings 'n', 's', 'e' and 'w'. Is there a pre-defined method for this?
If not, how can this be done?
I don't think there's a built-in method you could use. If arr is your array, you could do the following.
directions = ['n', 's', 'e', 'w']
arr.any? && (arr-directions).empty?
Some examples:
arr = ['n', 's', 'n']
arr.any? && (arr-directions).empty?
#=> true
arr = ['n', 's', 'f']
arr.any? && (arr-directions).empty?
#=> false
arr = ['f', 'g']
arr.any? && (arr-directions).empty?
#=> false
arr = []
arr.any? && (arr-directions).empty?
#=> false
You can use grep and grep_v with regex:
def news? arr
r = /[news]/
!arr.grep(r).empty? && arr.grep_v(r).empty?
end
Using Cary's tests (albeit slightly modified):
news? ['n', 's', 'n'] #=> true
news? ['n', 's', 'f'] #=> false
news? ['f', 'g', 'h'] #=> false
news? [] #=> false
There isn't any built-in function as far as I'm aware. You could do something like below or try the include? method on your array.
array.each do |element|
if element != 'n' && element != 's' && element != 'e' && element != 'w'
return false
end
end
return true
This should go through each element of the array and compare each element to 'n','s','e', and 'w'. If it finds something that doesn't match, it returns false. If it makes it all the way through without finding anything out of the ordinary, it returns true. You may want to check for an empty string at the beginning also.

How do I make each sentence into a nested list?

I'm working with a text file that looks like this; (The words are in Swedish)
['1', 'Denna', '_', 'DET', 'DT', 'UTR|SIN|DEF', '2', 'DT', '_', '_\n']
['2', 'predestination', '_', 'NOUN', 'NN', 'UTR|SIN|IND|NOM', '7', 'SS', '_', '_\n']
['3', 'till', '_', 'ADP', 'PP', '_', '2', 'ET', '_', '_\n']
['4', 'en', '_', 'DET', 'DT', 'UTR|SIN|IND', '6', 'DT', '_', '_\n']
.....
There are about 500 sentences of various lenghts; each line describes one word. The first list element gives the word's position in the sentence.
I need my program to make a nested list from the entries for each sentence (one sub-list for each sentence). Every new sentence starts with position '1', and they are separated by empty lines. At the moment all my lines are in one list.
I would like to do something like:
l = []
for line in list:
if line[0] == '1':
l.append(line)
... then append every line that follows until it reaches '1' again, where I start with a new sub-list.
Some ides on how to do it? How could I make this recursive?
This is not a naturally recursive process; it's iterative. A simple loop will do the job.
alla = []
forst = True
for line in list:
if line[1] == '1':
# ny mening
if not forst:
alla.append(mening)
forst = False
mening = []
mening.append(line)
Since the trigger for each append is the start of the sentence, you still have one sentence left to add. I'll leave that part for you to do. :-)

Depth First Search in C

If I have to iterate through a table of hexagonal cells checking for text inside them by conducting a recursive depth first search, arranged as shown: [Typing it out on StackOverflow apparently doesn't keep the formatting.]
Example 1:
Example 2:
What would be the best way to identifying them as "cells?" In other words, besides removing the textual diagonal lines and converting them into a 2D array with just numbers in it, what would be the best way to tell the computer in code to recognize x certain number of y characters resembles a "cell?"
Thanks in advance.
Easiest way to represent a hexagonal grid would be plain 2-d array with special rule about neighborhood of the cells. Take your second case for example, in matrix form it would be:
char M[][] =
{
{ 'b', 'g', 'g', 'b', ' ' },
{ 'g', ' ', 'B', 'B', 'B' },
{ 'g', 'B', ' ', 'b', 'g' },
{ 'B', ' ', 'g', 'g', 'g' }
}
Element in column m in row n is neighbor with:
elements in columns m and m + 1 in row n - 1
elements in columns m - 1 and m + 1 in row n
elements in columns m - 1 and m in row n + 1

Matlab - How to compare values in a cell array?

I have a set of inputs and one output declared in a cell array like that:
A = {'a', 'f', 'c', 'b';
'b', 'f', 'c', 'a';
'a', 'f', 'b', 'c';
'c', 'f', 'b', 'a';
'c', 'f', 'a', 'b';
'b', 'f', 'a', 'c' }
where the first column is an output, and the rest are the inputs used, for each output.
I need to compare the values to reduce the calculation time.
So, the thing is, for equals outputs, I wanna know if the inputs are the same, a important remark.. the order of values desn't metter, so, when comparing f c b with f b c it is the same.
I need this because, acttualy, my data set is a 5040 x 7 cell array and I need to put them into a intorpolation function.
I thought in something like
if the value of the output column is equal to the another value of the same column, check if the value of inputs are all the same, using, ismember function.
But I can not arrive to a code that works.
Any help, please?
First, since you don't care about the order of the inputs, I would sort each of the rows:
[T, N] = size(A);
for t = 1:T
Asorted(t,1) = A(t,1);
Asorted(t,2:N) = sort(A(t,2:N));
end
Now you want to find all of the duplicate rows. A simple way to do this is first to convert to a character array, and use the unique function --
B = cell2mat(Asorted);
[C, ii, jj] = unique(B,'rows');
Now C contains the unique rows of B, ii contains the indexes of the unique rows, and jj labels each of the rows of B depending on which unique value it has.
If you wanted to filter out all of the duplicate rows from A, you can now do
Afiltered = A(ii, :);
This results in:
Afiltered =
'a' 'f' 'b' 'c'
'b' 'f' 'a' 'c'
'c' 'f' 'a' 'b'

How can I efficiently find unique cell arrays within a set of cell arrays in MATLAB?

I need to find only unique cell arrays within a set of cell arrays. For example, if this is my input:
I = {{'a' 'b' 'c' 'd' 'e'} ...
{'a' 'b' 'c'} ...
{'d' 'e'} ...
{'a' 'b' 'c' 'd' 'e'} ...
{'a' 'b' 'c' 'd' 'e'} ...
{'a' 'c' 'e'}};
Then I would want my output to look like this:
I_unique = {{'a' 'b' 'c' 'd' 'e'} ...
{'a' 'b' 'c'} ...
{'d' 'e'} ...
{'a' 'c' 'e'}};
Do you have any idea how to do this? The order of elements in the output doesn't matter, but efficiency does since the cell array I could be very large.
If your cells contain only sorted single characters then you can retain just the unique sequences using:
>> I = {{'a' 'b' 'c' 'd' 'e'} {'a' 'b' 'c'} {'d' 'e'} {'a' 'b' 'c' 'd' 'e'} {'a' 'b' 'c' 'd' 'e'} {'a' 'c' 'e'}};
>> I_unique = cellfun(#char, I, 'uniformoutput', 0);
>> I_unique = cellfun(#transpose, I_unique, 'uniformoutput', 0);
>> I_unique = unique(I_unique)
I_unique =
'abc' 'abcde' 'ace' 'de'
You can then split the resulting cells into single characters again:
>> I_unique = cellfun(#transpose, I_unique, 'uniformoutput', 0);
>> I_unique = cellfun(#cellstr, I_unique, 'uniformoutput', 0);
>> I_unique = cellfun(#transpose, I_unique, 'uniformoutput', 0);
>> I_unique{:}
ans =
'a' 'b' 'c'
ans =
'a' 'b' 'c' 'd' 'e'
ans =
'a' 'c' 'e'
ans =
'd' 'e'
EDIT: Updated to use a more efficient algorithm.
If efficiency is tantamount due to a large number of sets in I, then your best option is probably to roll your own optimized loops. This problem bears some similarity to a previous question about how to efficiently remove sets that are subsets of or equal to another. The difference here is that you are not concerned with removing subsets, just duplicates, so the code in my answer to the other question can be modified to further reduce the number of comparisons made.
First we can recognize that there's no point in comparing sets that have different numbers of elements, since they can't possibly match in that case. So, the first step is to count the number of strings in each set, then loop over each group of sets that have the same number of strings.
For each of these groups, we will have two nested loops: an outer loop over each set starting at the end of the sets, and an inner loop over every set preceding that one. If/When the first match is found, we can mark that set as "not unique" and break the inner loop to avoid extra comparisons. Starting the outer loop at the end of the sets gives us the added bonus that sets in I_unique will maintain the original order of appearance in I.
And here is the resulting code:
I = {{'a' 'b' 'c' 'd' 'e'} ... %# The sample cell array of cell arrays of
{'a' 'b' 'c'} ... %# strings from the question
{'d' 'e'} ...
{'a' 'b' 'c' 'd' 'e'} ...
{'a' 'b' 'c' 'd' 'e'} ...
{'a' 'c' 'e'}};
nSets = numel(I); %# The number of sets
nStrings = cellfun('prodofsize',I); %# The number of strings per set
uniqueIndex = true(1,nSets); %# A logical index of unique elements
for currentSize = unique(nStrings) %# Loop over each unique number of strings
subIndex = find(nStrings == currentSize); %# Get the subset of I with the
subSet = I(subIndex); %# given number of strings
for currentIndex = numel(subSet):-1:2 %# Outer loop
for compareIndex = 1:currentIndex-1 %# Inner loop
if isequal(subSet{currentIndex},subSet{compareIndex}) %# Check equality
uniqueIndex(subIndex(currentIndex)) = false; %# Mark as "not unique"
break %# Break the inner loop
end
end
end
end
I_unique = I(uniqueIndex); %# Get the unique values

Resources