<jupyter_start><jupyter_text>NumPy basics<jupyter_code>import numpy as np<jupyter_output><empty_output><jupyter_text>What is NumPy?The [NumPy homepage](www.numpy.org) explains: * NumPy is a fundamental package for scientific computing in Python* it has a powerful N-dimensional array object: ``np.array``  creating a numpy arrayCreate a 3 x 3  array:<jupyter_code>foo_a = np.array([[2., 2., 3.], [4., 5., 6.], [7., 8., 9.]])

foo_a.shape  # return the dimensions of the array
print foo_a<jupyter_output><empty_output><jupyter_text>Create a 3 x 3 array with random numbers, drawn from a uniform distribution over ``[0, 1)``:<jupyter_code>foo_rand = np.random.rand(3, 3)
print foo_rand<jupyter_output><empty_output><jupyter_text>indexingKeep in mind: Python is **zero-indexed**. Show the first row of the array:<jupyter_code>foo_a[0, :]<jupyter_output><empty_output><jupyter_text>Show the last column:<jupyter_code>foo_a[:, -1]<jupyter_output><empty_output><jupyter_text>slicing, viewing, copying  referenceSimple assignments do not copy the object, but create a reference to the original object: ``foo_a`` and ``foo_b`` are different names for the same object.<jupyter_code>foo_b = foo_a
foo_b
foo_b is foo_a<jupyter_output><empty_output><jupyter_text>This means, that any changes made to ``foo_a`` are reflected in ``foo_b``:<jupyter_code>foo_a[0, 0] = 1.
print("We changed foo_a:")
print foo_a
print("But the same changes apply to foo_b:")
print foo_b<jupyter_output><empty_output><jupyter_text>slicing<jupyter_code>b_slice = foo_b[0, :]
b_slice<jupyter_output><empty_output><jupyter_text>``b_slice`` is called a _view_. It is a new object but shares all data with ``foo_b``.<jupyter_code>b_slice[0] = 7.
b_slice
foo_b<jupyter_output><empty_output><jupyter_text>Any changes made to the view are also reflected in the full object. This makes looping over objects easy, as one don't have to worry about indices:<jupyter_code>for row in foo_b:
    row *= 10.
    print foo_b<jupyter_output><empty_output><jupyter_text>and, since ``foo_b`` is a reference to ``foo_a``:<jupyter_code>foo_a<jupyter_output><empty_output><jupyter_text>copying<jupyter_code>foo_c = foo_a.copy()
foo_c
foo_c is foo_a<jupyter_output><empty_output><jupyter_text>``copy()`` creates a deep copy of ``foo_a``, i.e., a new object containing a copy of the content of ``foo_a``. Making changes to this copy does not change the original object:<jupyter_code>foo_c[0, 1] = 1.
foo_c
foo_a<jupyter_output><empty_output><jupyter_text>stacking arrays<jupyter_code>foo_d = foo_a.copy() / 10
foo_d<jupyter_output><empty_output><jupyter_text>stack the array ``foo_a`` and ``foo_d`` **horizontally**:<jupyter_code>stacked = np.hstack((foo_a, foo_d))
stacked<jupyter_output><empty_output><jupyter_text>stack the array ``foo_a`` and ``foo_d`` **vertically**:<jupyter_code>stacked = np.vstack((foo_a, foo_d))
stacked<jupyter_output><empty_output><jupyter_text>doing the opposite: splittingsplit the array vertically in 2 equally sized arrays:<jupyter_code>foo_x = np.vsplit(stacked, 2)

# what is the returned object?
type(foo_x)
len(foo_x)  # how long is the list?
print foo_x[0]
print foo_x[1]<jupyter_output><empty_output><jupyter_text>simple operations on numpy arrays minimum and maximum<jupyter_code>print foo_a  # to have a point of reference
print foo_a.min()
print foo_a.max()<jupyter_output><empty_output><jupyter_text>sum<jupyter_code>foo_a.sum()<jupyter_output><empty_output><jupyter_text>print the sum per rows and per columns:<jupyter_code>print foo_a.sum(axis=0)
print foo_a.sum(axis=1)<jupyter_output><empty_output><jupyter_text>cumulative sum<jupyter_code>foo_a.cumsum()<jupyter_output><empty_output><jupyter_text>mean<jupyter_code>foo_a.mean()
np.mean(foo_a)<jupyter_output><empty_output><jupyter_text>Excursus: don't import *<jupyter_code>print sum(foo_a)
print np.sum(foo_a)
from numpy import *
print sum(foo_a)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12161471640265713, 'fraction_numerical': 0.009708737864077669, 'mean_word_length': 8.233490566037736, 'pattern_counts': {'":': 0, '<': 93, '<?xml version=': 0, '>': 93, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, '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': '23', 'dir': 'jupyter-structured-clean-dedup', 'id': '545834', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1531, 'n_tokens_neox': 1492, 'n_words': 341, 'path': 'intro_to_numpy/ipython_notebooks/numpy_basics.ipynb', 'repo_name': 'britta-wstnr/PyFIN', 'size': '3914'}