<jupyter_start><jupyter_text>NumpyThe basis of most scientific programming in Pyhton is the *numerical Python* library, `numpy`. NumPy gives us many tools - including a fast and efficient data type, the `numpy Array` - for working with numerical data.  Numpy ArrayNumPy is built around the `array`. This is a data structure defined in NumPy which is *ordered* and *mutable*, must like the `list`. Although very similar to the list, the numpy array only allows *numerical* data as elements, like the `int` and `float`. Let's explore!<jupyter_code># Frist we need to import the numpy package. It is commonly shortened to "np"
import numpy as np<jupyter_output><empty_output><jupyter_text>The easiest way to define numpy arrays is to define a list or tuple, and convert it to an array with the `numpy.array()` function.<jupyter_code>a = [0, 1, 2, 3, 4]
b = np.array(a)
print(type(a))
print(type(b))<jupyter_output><class 'list'>
<class 'numpy.ndarray'><jupyter_text>We can index and slice numpy arrays much like lists:<jupyter_code>print(b[0], b[1:3], b[-1])<jupyter_output>0 [1 2] 4<jupyter_text>Try running the following to get help on the NumPy array<jupyter_code>help(np.ndarray)<jupyter_output><empty_output><jupyter_text>Woah. That's a really long help page. Often when you are working with a new package, `help()` won't be the most convenient or easy to read way to get help. Instead, we can search for online *documentation* for the package we are using.If you Google **numpy documentation**, you will likely see links to info about *numpy* and another package we will explore later, *scipy*. If you follow the links to **NumPy**, you should find a [NumPy user Guide](https://docs.scipy.org/doc/numpy-1.15.0/user/index.html) and from there, several pages of tutorials and documentation about the package. The [Quickstart tutorial](https://docs.scipy.org/doc/numpy-1.15.0/user/quickstart.html), will give a much more legible intro to the package. Numpy AttributesNumPy arrays have some built in **attributes**, i.e. info stored in an object, accessible with `object.attribute` (note: no parentheses after).<jupyter_code># Let's print some attributes of our b array
print("Num dimensions:", b.ndim,
      "\nShape:", b.shape,
      "\nSize:", b.size)<jupyter_output>Num dimensions: 1 
Shape: (5,) 
Size: 5<jupyter_text>A common way to define NumPy arrays with with the `arange` function.<jupyter_code>np.arange(10)
help(np.arange)<jupyter_output><empty_output><jupyter_text>The numpy `arange` function allows us to quickly build integer arrays. It takes `start`, `stop`, and `step` as arguments.<jupyter_code>x = np.arange(1, 10)
y = np.arange(2, 20, 2)
print(x)
print(y)<jupyter_output>[1 2 3 4 5 6 7 8 9]
[ 2  4  6  8 10 12 14 16 18]<jupyter_text>We can apply any mathematical operation to a NumPy array, and it will apply that operation to every element in the array.<jupyter_code>x = np.arange(-3, 4)
y = x**2
print(y)<jupyter_output>[9 4 1 0 1 4 9]<jupyter_text>Another way to make NumPy arrays is with the `linspace()` function. This allows us to choose the bounds of an interval and the number of points we want to divide it into. Numpy also has useful math constants like `pi` and `e` and math functions like `sin`, `cos`, `tan`.<jupyter_code>import matplotlib.pyplot as plt
x = np.linspace(-2*np.pi, 2*np.pi, 100)
y = np.sin(x)
plt.plot(x, y)
# Linspace can be useful for adding more resolution to continuous functions
xarange = np.arange(-np.pi, np.pi)
yarange = np.cos(xarange)

xlinspace = np.linspace(-np.pi, np.pi, 1000)
ylinspace = np.cos(xlinspace)

plt.subplot(1, 2, 1)
plt.plot(xarange, yarange)

plt.subplot(1, 2, 2)
plt.plot(xlinspace, ylinspace)<jupyter_output><empty_output><jupyter_text>If we want to plot a bell curve we can use the `np.random` module to randomly sample a normal distribution.<jupyter_code>norm = np.random.standard_normal(100000) # Draw 1000 random points from normal distribution
hist, bins = np.histogram(norm, bins=10, density=True) # Make histogram of our samples
plt.plot(bins[1:], hist)
hist, bins = np.histogram(norm, bins=100, density=True)
plt.plot(bins[1:], hist)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10993249758919961, 'fraction_numerical': 0.023625843780135006, 'mean_word_length': 5.257918552036199, 'pattern_counts': {'":': 0, '<': 38, '<?xml version=': 0, '>': 38, 'https://': 2, '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': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '8073', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1462, 'n_tokens_neox': 1365, 'n_words': 525, 'path': 'todo/sp_numpy.ipynb', 'repo_name': 'RyleighDavis/spirl', 'size': '4148'}