<jupyter_start><jupyter_text>Python for Data Science Mini Tutorial  Jupyter[Jupyter](https://jupyter.org) is a browser front-end connected to an instance of IPython which allows quick testing, allows to create documents that intertwines code, output, images, and text. This is great for prototyping, demonstrations and tutorials, but terrible for actual coding.   Hello<jupyter_code>print("Hello World!")
a = 5
b = 3.2
print("a: ", a, "Type: ", type(a))
print("b: ", b, "Type: ", type(b))
text = "Hello World!"
print("Text: ", text, type(text))
# Definición de la función para calcular la serie de Fibonacci
def fibonacci(n):
    """
    Devuelve una lista conteniendo la serie de Fibonacci hasta n.
    """
    resultado = []
    a, b = 0, 1
    while a < n:
        resultado.append(a)
        a, b = b, a+b
    return resultado
# Utilización de la función
fib100 = fibonacci(100)
print(fib100)<jupyter_output><empty_output><jupyter_text>LATEX Code  Teorema de Pitágoras**Fecha: 495 AC**Si a y b son catetos y c la hipotenusa de un triángulo rectángulo:$c^2 = a^2 + b^2$  HTML Code Visit W3Schools Julio   Numpy [Numpy](http://www.numpy.org) is designed to handle large multidimensional arrays and enable efficient computations with them. In the back, it runs pre-compiled C code which is much faster than, say, a Python `for` loop<jupyter_code>import numpy as np<jupyter_output><empty_output><jupyter_text>Indexing and slicing Numpy arrays can be indexed and sliced like regular python arrays<jupyter_code>a_py = [1, 2, 3, 4, 5, 6, 7, 8, 9]
a_np = np.array(a_py)
print(a_py[3:7:2], a_np[3:7:2])
print(a_py[2:-1:2], a_np[2:-1:2])
print(a_py[::-1], a_np[::-1])<jupyter_output><empty_output><jupyter_text>But you can also use arrays to index other arrays<jupyter_code>idx = np.array([7,2])
a_np[idx]
# a_py[idx]<jupyter_output><empty_output><jupyter_text>Which allows convenient querying, reindexing and even sorting<jupyter_code>ages = np.random.randint(low=30, high=60, size=10)
heights = np.random.randint(low=150, high=210, size=10)

print(ages)
print(heights)
print(ages < 50)
print(heights[ages < 50])
print(ages[ages < 50])
shuffled_idx = np.random.permutation(10)
print(shuffled_idx)
print(ages[shuffled_idx])
print(heights[shuffled_idx])
sorted_idx = np.argsort(ages)
print(sorted_idx)
print(ages[sorted_idx])
print(heights[sorted_idx])<jupyter_output><empty_output><jupyter_text>Broadcasting When Numpy is asked to perform an operation between arrays of differents sizes, it "broadcasts" the smaller one to the bigger one.<jupyter_code>a = np.array([4, 5, 6])
b = np.array([2, 2, 2])
a * b
a = np.array([4, 5, 6])
b = 2
a * b<jupyter_output><empty_output><jupyter_text>The two snippets of code above are equivalent but the second is easier to read and also more efficient.<jupyter_code>a = np.arange(10).reshape(1,10)
b = np.arange(12).reshape(12,1)
print(a)
print(b)
print(a * b)<jupyter_output><empty_output><jupyter_text>Matplotlib<jupyter_code>%matplotlib inline
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = [10, 7]<jupyter_output><empty_output><jupyter_text>[Matplotlib](https://matplotlib.org) is the go-to library to produce plots with Python. It comes with two APIs: a MATLAB-like that a lot of people have learned to use and love, and an object-oriented API that we recommend using.<jupyter_code>x = np.linspace(-2*np.pi, 2*np.pi, 400)
y = np.tanh(x)
fig, ax = plt.subplots()
ax.plot(x, y)<jupyter_output><empty_output><jupyter_text>You can plot multiple subplots in the same figure, or multiple functions in the same subplot<jupyter_code>x = np.linspace(0, 2*np.pi, 400)
y1 = np.tanh(x)
y2 = np.cos(x**2)
fig, axes = plt.subplots(1, 2, sharey=True)
axes[1].plot(x, y1)
axes[1].plot(x, -y1)
axes[0].plot(x, y2)<jupyter_output><empty_output><jupyter_text>Matplotlib also comes with a lot of different options to customize, the colors, the labels, the axes, etc.For instance, see this [introduction to matplotlib](https://nbviewer.jupyter.org/github/jrjohansson/scientific-python-lectures/blob/master/Lecture-4-Matplotlib.ipynb)  Pandas [Pandas](http://pandas.pydata.org) is a library that provides a set of tools for data analysis (Python Data Analysis Library).<jupyter_code>import pandas as pd<jupyter_output><empty_output><jupyter_text>Pandas dataframes can be created by importing a CSV file (or TSV, or JSON, or SQL, etc.)<jupyter_code>df = pd.read_csv("../datasets/adult.csv")
df.head()
df.describe()<jupyter_output><empty_output><jupyter_text>Pandas columns are also Numpy arrays, so they obey to the same indexing magic<jupyter_code>df[df['age'] > 80]<jupyter_output><empty_output><jupyter_text>They also provide most functionality you would expect as database user (`df.sort_values`, `df.groupby`, `df.join`, `df.concat`, etc.)  Plot Age Histogram<jupyter_code>df['age'].hist()<jupyter_output><empty_output><jupyter_text>Plot Income by Gender<jupyter_code>df['income_bin'] = df.income == " >50K"
plt.figure()
plt.title("By gender")
grouped = df.groupby("gender")
grouped.income_bin.mean().plot.barh()
fig, ax = plt.subplots(1,2)
ax[0].hist(df['age'], label="age")
ax[0].set_xlabel("age")
ax[1].hist(df['education-num'], label="education-num")
ax[1].set_xlabel("education-num")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13458975823339045, 'fraction_numerical': 0.023415191319246145, 'mean_word_length': 6.148299319727891, 'pattern_counts': {'":': 0, '<': 65, '<?xml version=': 0, '>': 63, 'https://': 3, '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': '15', 'dir': 'jupyter-structured-clean-dedup', 'id': '428057', 'license': 'MIT', 'n_tokens_mistral': 2054, 'n_tokens_neox': 1940, 'n_words': 510, 'path': '1-Introduction/notebooks/0-Python_Data_Science-Tutorial.ipynb', 'repo_name': 'phermar/aprendiz-machine-learning', 'size': '5253'}