# NumPy Basics: Part 2¶

Ha Khanh Nguyen (hknguyen)

## 1. Array Indexing & Slicing¶

### 1.1 Indexing & slicing with one-dimensional arrays¶

• One-dimensional arrays are simple; on the surface they act similarly to Python lists:
• An important first distinction from Python’s built-in lists is that array slices are views on the original array.

• This means that the data is not copied, and any modifications to the view will be reflected in the source array.
• We will test this with the following code segment:

• Now let's change the values in arr_slice!
• This is not the case with list at all! (watch the video or try it out yourself)
• Note: If you want a copy of a slice of an ndarray instead of a view, you will need to explicitly copy the array—for example, arr[5:8].copy().
• The "bare" slice [:] will assign to all values in an array:

### 1.2 Indexing & slicing with higer-dimension arrays¶

• In a two-dimensional array, the elements at each index are no longer scalars but rather one-dimensional arrays:
• arr2d[i] with return the i+1-th row of the array in a 2d-array case.
• To select an individual element:

• Now, let's try slicing with 2d-array!
• What's if we want to slice along axis 1 only?
• When slicing like this, you always obtain array views of the same number of dimensions. By mixing integer indexes and slices, you get lower dimensional slices.

• Note that assigning values to a slice expression assigns to the whole selection:

### 1.3 Boolean Indexing¶

• Let’s consider an example where we have some data in an array and an array of names with duplicates.
• Now, we will generate some random normally distributed data (more on this later):
• Suppose each name corresponds to a row in the data array and we wanted to select all the rows with corresponding name 'Bob'.
• Selecting two of the three names to combine multiple boolean conditions, use boolean arithmetic operators like & (and) and | (or):
• Setting values with boolean arrays works in a common-sense way. To set all of the negative values in data to 0 we need only do:

## 2. Universal Functions: Fast Element-wise Array Functions¶

• A universal function, or ufunc, is a function that performs element-wise operations on data in ndarrays.
• Many ufuncs are simple element-wise transformations, like sqrt or exp:
• These are referred to as unary ufuncs.
• Others, such as add or maximum, take two arrays (thus, binary ufuncs) and return a single array as the result:

### Exercise¶

Convert the following code segment from built-in Python list to NumPy arrays:

## 3. Pseudorandom Number Generator¶

• The numpy.random module supplements the built-in Python random with functions for efficiently generating whole arrays of sample values from many kinds of probability distributions:
• We say that these are pseudorandom numbers because they are generated by an algorithm with deterministic behavior based on the seed of the random number generator.
• You can change NumPy’s random number generation seed using np.random.seed:
• Here is the documentation for the pseudorandom number generator functions of each distribution.