boolean indexingthis advanced indexing occurs when the reference object is an array of boolean values this is used when we want to access data based on some conditionsin that caseboolean indexing can be used we will illustrate it with an example suppose in one arraywe have the names of some cities and in another arraywe have some data related to those cities in [ ]cities np array(["delhi","bangalore","mumbai","chennai","bhopal"]city_data np random randn( , city_data out[ ]:array([ - - ] - ][- - - ][- - - ] ]]in [ ]city_data[cities =="delhi"out[ ]array([ - - ]]we can also use boolean indexing for selecting some elements of an array that satisfy particular condition for examplein the previous array suppose we want to only select non-zero elements we can do that easily using the following code in [ ]city_data[city_data > out[ ]array( ]we observe that the shape of the array is not maintained so we directly cannot always use this indexing method but this method is quite useful in doing conditional data substitution suppose in the previous casewe want to substitute all the non-zero values with we can achieve that operation by the following code in [ ]city_data[city_data > city_data out[ ]array([ - - ] - ][- - - ][- - - ] ]]operations on arrays at the start of this sectionwe mentioned the concept of universal functions (ufuncsin this sub-sectionwe learn some of the functionalities provided by those functions most of the operations on the numpy arrays is achieved by using these functions numpy provides rich set of functions that we can leverage for various operations on arrays we cover some of those functions in briefbut we recommend you to always refer to the official documentation of the project to learn more and leverage them in your own projects universal functions are functions that operate on arrays in an element by element fashion the implementation of ufunc is vectorizedwhich means that the execution of ufuncs on arrays is quite fast the ufuncs implemented in the numpy package are implemented in compiled code for speed and efficiency but it is possible to write custom functions by extending the numpy ufunc class of the numpy package