<jupyter_start><jupyter_text>Boolean arrays<jupyter_code># Import the array library
import numpy as np<jupyter_output><empty_output><jupyter_text>We are building up to an answer to the [three girlsproblem](../code-basics/three_girls).  At the end of the [lists page](../data-types/lists), we found a way to simulate one family, and get a count.Now we know about function arguments, and arrays, we can simplify the listversion, like this:<jupyter_code># Make an array of four random integers that are either 0 or 1.
# 1 means a girl.
family = np.random.randint(0, 2, size=4)
family
# Add up the integers to count the number of girls.
count = np.sum(family)
count<jupyter_output><empty_output><jupyter_text>Our interest in how whether of the `count` value is equal to 3. We can look atthat number and write down "Yes" if the number is equal to 3 and "No"otherwise, but we would like the computer to do that routinework for us.  We use [comparison](../data-types/Comparison):<jupyter_code>is_three = count == 3
is_three<jupyter_output><empty_output><jupyter_text>True means our simulation found a family with three girls, and False means wefound a family some other number of girls.In a while, we are going to simulate a very large number of these families, but for now, let us simulate 5 families, in a somewhat laborious way:<jupyter_code># Make an array to store the counts for each family.
counts = np.zeros(5)
# Make five families, store the counts.
family = np.random.randint(0, 2, size=4)
counts[0] = np.sum(family)
# Second family
family = np.random.randint(0, 2, size=4)
counts[1] = np.sum(family)
# Third
family = np.random.randint(0, 2, size=4)
counts[2] = np.sum(family)
# Fourth
family = np.random.randint(0, 2, size=4)
counts[3] = np.sum(family)
# Fifth.
family = np.random.randint(0, 2, size=4)
counts[4] = np.sum(family)
# Show the counts
counts<jupyter_output><empty_output><jupyter_text>Each value in `counts` is the number of girls in one simulated family.Now we have 5 numbers for which we want to ask the question - is this numberequal to 3?  We would like five corresponding True or False values.Here is where arrays continue to work their magic - we can get this result with a single expression:<jupyter_code>are_three = counts == 3
are_three<jupyter_output><empty_output><jupyter_text>`are_three` is an array with 5 elements, one for every element in the array wecompared, `counts`.`are_three` is a *Boolean array* because it contains only Boolean (True, False) values.We can see what kind of data the array contains by looking at the `dtype` attribute of the array.  Remember, an attribute is a value attached to another value. In this case it is a value attached to the `are_three` value.<jupyter_code>are_three.dtype<jupyter_output><empty_output><jupyter_text>Each element in `are_three` has the result of the comparison for thecorresponding element.  The code above is equivalent to doing:<jupyter_code># Make an array of Boolean type (the "dtype" argument)
are_three_longhand = np.zeros(5, dtype=bool)
# Do the comparisons one by one.
are_three_longhand[0] = counts[0] == 3
are_three_longhand[1] = counts[1] == 3
are_three_longhand[2] = counts[2] == 3
are_three_longhand[3] = counts[3] == 3
are_three_longhand[4] = counts[4] == 3
# Show the result
are_three_longhand<jupyter_output><empty_output><jupyter_text>Now we want to know how many of the `counts` values are equal to 3.  This isthe same as asking how many True values there are in `are_three` (or`are_three_longhand`.We can do this using the `np.count_nonzero` function.  It accepts an array as its argument, and returns the number of non-zero values in the array.  It turns out that `np.count_nonzero` treats True as non-zero, and False as zero, so `np.count_nonzero` on a Boolean array counts the number of True values:<jupyter_code>my_booleans = np.array([True, False, True])
np.count_nonzero(my_booleans)<jupyter_output><empty_output><jupyter_text>To see the number of times we found 3 in `counts`:<jupyter_code>np.count_nonzero(are_three)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08972146906581217, 'fraction_numerical': 0.013063840276066059, 'mean_word_length': 5.431061806656102, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '574708', 'license': 'CC-BY-4.0', 'n_tokens_mistral': 1331, 'n_tokens_neox': 1293, 'n_words': 512, 'path': 'arrays/boolean_arrays.ipynb', 'repo_name': 'uob-ds/cfd2021', 'size': '4057'}