0% found this document useful (0 votes)
7 views3 pages

Python Lab: Numpy & Pandas Basics

This document outlines the guidelines and tasks for Lab 1 of the X/HEC Data Science for Business course, focusing on Python, Numpy, and Pandas. It includes instructions for submission, coding practices, and a series of exercises designed to familiarize students with Python programming and data manipulation using Numpy. Key topics include string manipulation, array operations, and understanding value versus reference types in Python.

Uploaded by

ryanbalech1
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views3 pages

Python Lab: Numpy & Pandas Basics

This document outlines the guidelines and tasks for Lab 1 of the X/HEC Data Science for Business course, focusing on Python, Numpy, and Pandas. It includes instructions for submission, coding practices, and a series of exercises designed to familiarize students with Python programming and data manipulation using Numpy. Key topics include string manipulation, array operations, and understanding value versus reference types in Python.

Uploaded by

ryanbalech1
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

X/HEC Datascience for Business

2024/2025 Mathurin Massias

Lab no 1 : Introduction: Python, Numpy, Pandas

- Evaluation -

The Lab is done by pairs. There is no exception. On Moodle you have a section called “Lab
1 submission” for the first class. Each student in the pair must upload their notebook, with the
filename constructed as fistname1_LASTNAME1_firstname2_LASTNAME2.ipynb, where you have sub-
stituted your respective first and last names. Ex : mathurin_MASSIAS_sylvain_COMBETTES.ipynb.
There is no evaluation if you don’t respect this. If code is shared between groups, both groups
get 0. Read the intro slides on what’s expected of you in the labs.

Important preliminary remarks


We use jupyter notebook or jupyter lab, potentially with Visual Studio Code, for all practical
sessions. Some important points to remember :

- Loading -

import sklearn # import a package


import numpy as np # import a package under an alias
import [Link] as plt # import a submodule with an alias
from sklearn import linear_model # import a submodule
from os import mkdir # import a peculiar function

- Using standard help -

When facing a difficulty, you are strongly encouraged to refer to the online documentation of pandas,
numpy, etc. It should become a reflex to look for the answer in the doc or on stackoverflow.
linear_model.LinearRegression? # to get some help on the LinearRegression object

- Package versions -

print(np.__version__) # to get a package version

Strings
1) From a string containing all the alphabet letters, generate the string cfilorux using slicing (notice
the pattern : this is the 3rd letter, then the 6th, then the 9th, etc). Do the same for the strings
vxz and zxvt (again, notice the patterns). Note : don’t type the whole alphabet yourself, use the
string module.
2) Declare a string variable " XHEC DataScience for Business ". Make it all lowercase. Remove
spaces at the beginning and at the end, but not between words. Replace all e’s with E’s.

page 1
3) Display the number π with 9 decimal digits ([Link]). Don’t cast a number to string, and don’t use
round : use Python’s string formatting instead (either the format method, either the % operator,
either an f-string – the latter is considered more modern).
4) Count the number of occurrences of each character in the string s = "HelLo WorLd!!" (in real
life, you should use a [Link] ; here, you are asked to code the method yourself).
Output a dictionary that to each character associates the number of occurrences in this string. In
this question, we consider that lower and upper case characters are the same (e.g. your dictionary
should not have both a L and a l entry).

Fast computations with numpy ; basic plots.


Hint : useful functions : [Link], [Link], [Link], [Link] for instance. The
whole [Link] module contains interesting Linear Algebra functions. [Link] contains func-
tions to generate arrays of (pseudo-) random numbers.
In all this section, unless asked explicitly, you cannot use for/while loops (they are slow in native
python).
5) Compute 0.1 + 100 - 100. Using ==, check if it is equal to 0.1. Comment. Compare the two
floating point numbers again with an appropriate numpy function.
6) Create a list (resp. a numpy array) containing all square numbers from 1, 4, ... to 121, using a for
loop (resp. only numpy). Why should you use arrays instead of loops whenever possible ?
7) Create an array containing integers from 2 to 14 by step of 3 (2, 5, 8, ...). Create an array with 15
equispaced valued from 0 to 1 included. Use numpy built-in functions.
ś8 2
8) Compute 2 k“1 4k4k2 ´1 (approximate 8 by a large number n) using a for loop. Propose a ver-
sion without loop, using only numpy (see [Link]). Measure the time taken by both versions
using [Link](). You should display the results with a relevant number of significant digits, e.g.
not 0.002487976589749873 seconds. Use the ipython magic %timeit again to measure time of one
version. Why is it better than [Link] ?
9) (row and column vectors, aka numpy only knows 1D arrays) Compute the dot product (aka scalar
product) of [Link](5) and [Link](5). What is the shape of [Link](5) ? How many di-
mensions does this array have ? What is the shape of its transpose (use .T) ? What does transposing
1D arrays do ?
10) What does reshape do in M = [Link](12).reshape(2, 6) ? What does M[:, ::3] do ? What
happens when you do [Link](3) * [Link](4)[:, [Link]] (this powerful tool is
known as broadcasting)
11) Create a random matrix M P R5ˆ6 with coefficients taken uniformly (and independently) in r´1, 1s.
Substract to each even column of M (say M[:, 0] is even), twice the value of the following (uneven)
column.
12) Replace the negative values in M by 0. Compute the mean of each row of M . Substract to each
row of M , its mean.
13) Create a random matrix M P R5ˆ10 with coefficients taken uniformly (and independently) in r´1, 1s.
Test whether G “ M J M is symmetric semi-definite positive, and that its eigenvalues are strictly
positive. Compute the rank of G. Compute the Euclidean norm of G. Compute the operator norm
of G (aka spectral norm, aka Schatten 2-norm). Compute the standard deviation of each column of
G.
14) Plot the functions x ÞÑ xd on the interval r´1, 2s for d P t2, 3, 4u with a decent resolution. Put a
xlabel, a ylabel, legend the 3 curves with d “ 2, d “ 3, d “ 4 respectively. Put a title.

Numpy advanced behavior


Numpy broadcasting
In this exercise, you can use neither lists nor for loops. You should use only numpy’s operations,
which are fast. An introduction to broadcasting is available here : [Link]
user/[Link].

page 2
15) Create an array with integers 1, 3, ..., 19. Subtract its mean to it. Observe than you can thus
subtract a number to an array, even though they do not have the same shape. Create an array with
3 lines and 4 columns, such that arr[i, j] = 4 * i + j (it thus contains integers from 0 to 11).
reshape will help.
16) Now, we subtract vectors to 2D arrays, using broadcasting. Take the previous (3, 4) array, and
subtract its column wise mean to it (easy). Subtract its row wise mean to it (technically more
challenging the first time, you can add an axis to a 1D array with arr[:, None]).
17) Using broadcasting and [Link], create an array of shape (3, 5) such that arr[i, j] = i * j.

Value and reference types


18) Create a variable a equal to 1000. Check the address in memory of the variable with the builtin id
function. Create a second variable b equal to 1000. What is the address in memory of b ? Create a
third variable c equal to a, check its address in memory. Do a += 1. How does it affect the values
of the three variables ? Why ?
19) Do the same but this time using a = [Link]([0, 1]), b = [Link]([0, 1]), c = a. What is
going on ?
20) (passing by value/passing by reference) Define a function f as follows : def f(a): a += 1. Call it
on a = 1, then on a = [Link](10). For both cases, check the value of a after calling f on it.
What’s the reason for this behavior ?
21) For two arrays a = [Link](10), b = [Link](10), what’s the difference between doing a = b
and a[:] = b ? What’s the difference between a = a + 1 and a += 1 ?

page 3

Common questions

Powered by AI

Numpy's reshape functionality plays a crucial role in array manipulation by reorganizing the structure without altering the underlying data. This function allows you to change the dimensions of an array to suit different computational needs while preserving data integrity. For example, converting a flat array into a matrix or reshaping a matrix into another dimensionality aids in facilitating operations that require specific input shapes, all while ensuring the total number of elements remains constant .

To ensure a matrix-dot-matrix operation like M'JM results in a symmetric matrix, matrix M should be subjected to an operation that inherently generates a symmetric result, such as multiplying it by its transpose. Testing for positive semi-definiteness involves checking if all eigenvalues of the resultant matrix are non-negative. Compute the eigenvalues and verify they are strictly positive for definitiveness. These tests confirm the matrix's symmetry and its positive semi-definite nature .

Importing entire packages versus specific submodules or functions has implications for memory usage and namespace clarity. Importing specific functions or submodules can reduce memory overhead and improve code clarity by limiting access to only the necessary components, minimizing potential naming conflicts. However, it could lead to more verbose code as each needed submodule must be explicitly imported. The choice depends on the application's complexity and performance requirements, with full package imports sometimes necessary for ease of use when many components are needed .

The trade-offs of using numpy's %timeit magic command over the basic time.time() method involve accuracy and overhead. %timeit automatically handles multiple executions and averages the runtime, providing more reliable and consistent performance measurements, especially for small, fast-executing code snippets. Meanwhile, time.time() is simpler and incurs less overhead but might not capture nuanced performance metrics due to its coarse granularity and single execution focus .

Broadcasting in numpy simplifies matrix operations by allowing arithmetic operations on arrays of different shapes without explicitly replicating the data. This feature extends smaller arrays across larger ones so that they have compatible shapes, enabling operations like row-wise or column-wise mean subtraction efficiently without the need for for loops. This is beneficial when manipulating arrays as it reduces memory overhead and increases computational speed .

Using broadcasting, modifications in a numpy array are applied to entire slices or segments of the array simultaneously, rather than iterating through elements individually. This means that operations can be performed over specific dimensions of arrays by matching the shape and dimensions appropriately, such as subtracting a column-wise mean from a 2D array. Traditional operations would require explicit loops or conditional handling to apply similar changes, whereas broadcasting automatically adjusts smaller arrays to match the larger array shapes .

Python's string formatting capabilities manage numerical precision and representation by allowing specific control over how numbers are displayed. For instance, using f-strings or the format method, numbers can be formatted to a specified number of decimal places without casting to a string or using round(). This is crucial for presenting numerical data cleanly and accurately in outputs, ensuring that precision is maintained while adapting the representation to the context, such as limiting to 9 decimal digits for π .

In the context of numpy arrays, memory addresses influence whether data is shared or copied between variables. When assigning a numpy array to another variable, such as 'c = a', both variables reference the same memory address, meaning changes to one affect the other. However, operations like 'a += 1' modify the data in place without altering the memory address, distinguishing them from operations like 'a = a + 1', which create a new array and change the reference. Understanding these differences is critical for efficient memory management and avoiding unintended side-effects .

Using numpy arrays instead of loops is recommended in Python because numpy is optimized for performance and can handle vectorized operations efficiently. Loops in native Python can be slow due to the interpreted nature of the language, whereas numpy operations are implemented in C and can be much faster. This performance advantage makes numpy more suitable for large-scale data manipulation and mathematical computations .

'np.allclose' is significant for comparing floating-point numbers because it considers the precision limitations of floating-point representations, providing a robust way to check for equality within a tolerance. Using '==' for comparing floating-point numbers can lead to erroneous results due to small floating-point arithmetic errors. 'np.allclose' mitigates this by allowing for a specified relative and absolute tolerance in the comparison .

You might also like