dormir? que es eso?

mail@pastecode.io avatar
unknown
python
a year ago
8.3 kB
4
Indexable
Never
# -*- coding: utf-8 -*-
"""
PSAL - Práctica 4.2

"""
def init() -> None:
    import numpy as np
    import matplotlib.pyplot as plt
    from tqdm import tqdm

    X1: np.ndarray = datos_desde_csv("X1_data.csv")
    X2: np.ndarray = datos_desde_csv("X2_data.csv")


# %% Funciones útiles
import numpy as np
import matplotlib.pyplot as plt
from tqdm import tqdm
from scipy import signal

def init() -> None:
    import numpy as np
    import matplotlib.pyplot as plt
    from tqdm import tqdm


def datos_desde_csv(direccion_archivo):
    return np.loadtxt(direccion_archivo, delimiter=";")    


def pintar_histograma_2d(x, y, bins=10):
    fig, ax = plt.subplots(1, 1)
    ax.hist2d(x=x, y=y, density=True, bins=bins)
    plt.show()


def get_diferencias(lista: np.ndarray, precision = 10) -> np.ndarray:
    '''
    Recorre un array devolviendo las diferencias de cada valor con su anterior.
    '''

    diferencias: np.ndarray = np.diff(lista, axis = 0)
    return np.round(diferencias, precision)


def get_nums_posiv(lista: list, comp: float) -> int:
    '''
    Devuelve la cantidad de elementos de un array que son mayores al valor
    comp.
    '''
    import numpy as np
    nplist: np.array() = np.array(lista)
    return len(nplist[nplist > comp])


def get_Z(proceso: np.ndarray) -> np.ndarray:
    '''
    X: 
    Devuelve Z_n de un proceso X_n
    '''
    # He intentado vectorizar la función utilizando np.vectorize de varias 
    # maneras, pero todas daban un mismo error que no he podido solucionar.
    return np.vstack((proceso[0], get_diferencias(proceso)))

# Yn = lambda n, aux: np.minimum(10, aux*Z2[n])n

def _generar_X3(Z1, Z2, Yn):

    pass 

def generar_X3(
        Z1: np.ndarray,
        Z2: np.ndarray,  
        Y_n: np.ndarray, 
        start_val: float = 10,
        mul: float = 1
    ) -> np.ndarray:
    '''
    Genera el proceso X3 correspondiente a la evolución de nuestra cartera.

    Devuelve: array de n + 1 filas y m columnas siendo n el número de filas
    de Z1 y m el número de columnas del mismo.
    '''
    assert np.shape(Z1) == np.shape(Z2), "La forma de las listas debe ser igual"
    

    # variaciones: np.ndarray = Z1*Y_n*mul
    width: int = np.shape(Z1)[1]

    # X_3[0] -> vector de 0s.
    # Generamos valor inicial (start_val * array de 1s)
    aux: np.ndarray = np.array(start_val*np.ones(width))
   
    for i in range(0,100):
        
        aux = np.vstack((aux, aux[i] + Z1[i]*Y_n(i, aux)))
    # aux = np.vstack((aux, variaciones))
    # aux = np.cumsum(aux, axis = 0)

    X3: np.ndarray = aux

    return X3


def calcular_evolucion_media(X3: np.ndarray) -> float:
    '''
    Devuelve la media de la evolución de un proceso.
    '''

    pass


def convolucionar(s1: np.ndarray, s2: np.ndarray) -> np.ndarray:
    '''
    Convoluciona cada fila de un array de nxm dimensiones con un array de 1-D de 
    i elementos.
    '''
    convol: function = lambda x: signal.fftconvolve(x, s2, mode = 'valid')
    return np.apply_along_axis(convol, 0, X2)



class Trading():
    
    def __init__(self, X1, X2):
        self.X1: np.ndarray = X1
        self.X2: np.ndarray = X2

    def Zs(self):
        pass
    
   
global X1
X1: np.ndarray = datos_desde_csv("X1_data.csv")
global X2
X2: np.ndarray = datos_desde_csv("X2_data.csv")


init()

# %% Apartado a

def apartado_a() -> float:
    '''Código del apartado a'''
    return np.mean(X1[-1])

apartado_a()

# %% Apartado b
def apartado_b() -> float:
    '''Código del apartado b.'''
    return np.max(X2[:,-1])

apartado_b()
# %% Apartado c
def apartado_c() -> float:
    '''
    Código del apartado c.
    '''
    # h[n]:
    h_n: function = lambda n: (1/n)*np.ones(n)

    conv1: np.ndarray = convolucionar(X2, h_n(5))
    conv2: np.ndarray = convolucionar(X2, h_n(9))

    meanconv1: float = np.mean(np.mean(conv1, axis = 1))
    meanconv2: float = np.mean(np.mean(conv2, axis = 1))

    return meanconv1, meanconv2


apartado_c()
    
# %% Apartado d
def apartado_d():
    '''Código del apartado d'''
    return get_Z(X1), get_Z(X2)

apartado_d()
# %% Apartado e
def apartado_e():
    '''Código del apartado e'''
    # Obtenemos Z_1[N] a partir de X1
    Z1: np.ndarray = get_Z(X1) 
    # Obtenemos Z_2[N] a partir de X2
    Z2: np.ndarray = get_Z(X2)
    # Obtenemos Z_1[n]*Z_2[n] (Z_1[n]*Y[n]) ya que Y[n] == Z_2[n] para este 
    # apartado.
    Z_conj: np.ndarray = Z1*Z2
    # Obtenemos la cantidad de elementos de cada columna de Z_conj que son 
    # mayores que 0.
    elementos_ganadores: list = np.sum(Z_conj > 0, axis=0)
    return np.mean(elementos_ganadores)

apartado_e()
# %% Apartado f
def apartado_f(n):
    '''Código del apartado f'''
    # No se si el enunciado se refiere al cambio de una n a otra o al cambio 
    # total después de haber computado el proceso para todos los valores de n 
    # positivos menores que 100, por lo que haré los dos casos
    
    # CAMBIO DE N A N + 1
    # Obtención de Zs:
    Z1, Z2 = get_Z(X1), get_Z(X2)
    Z_conj: np.ndarray = Z1*Z2

    if n:
        return np.mean(np.mean(Z_conj, axis = 0))
    # Media del cambio total:
    return np.mean(Z_conj[-1] - Z_conj[0])
# %% Apartado g
def apartado_g():
    '''
    Código del apartado g.
    '''
    # Obtención de Zs: 
    Z1, Z2 = get_Z(X1), get_Z(X2)

    # Definimos Y[n]
    def Y_n(n,aux):
        value = np.minimum(10*np.ones(np.shape(X1[0].T)[0]), 
                                                aux[-1])
        
        value = np.where(value < 0, 0, value)

        return value*Z2[n]

    X3: np.ndarray = generar_X3(Z1, Z2, Y_n, start_val=100)
    # Obtenemos las filas en los que algún elemento es menor que 0:

    # Array de booleanos
    X3lt = X3 < 0
    # Creamos un array unidimensional de booleanos donde se toma True si 1 o más
    # elementos de la columna son True.
    X3lt = np.any(X3lt, axis = 0)  # Size: np.shape(X3)[1]
    # Nos quedamos solo con los valores True.
    X3lt = X3lt[X3lt]
    return len(X3lt) / np.shape(X3)[1]  # Num col arruinadas / num experimentos.

# %% Apartado h
def apartado_h():
    '''Código del apartado h'''
    # Obtenemos Zs:
    Z1, Z2 = get_Z(X1), get_Z(X2)
    # Definimos Y[n]
    def Y_n(n,aux):
        value = np.minimum(10*np.ones(np.shape(X1[0].T)[0]), 
                                                aux[-1])
        
        value = np.where(value < 0, 0, value)

        return value*Z2[n]

    X3: np.ndarray = generar_X3(Z1, Z2, Y_n, start_val=100)
    get_index = lambda x: np.nonzero(x < 0)[0][0] if len(np.nonzero(x < 0)[0]) else None
    returnval: np.ndarray = np.apply_along_axis(get_index, 0, X3)
    return np.mean(returnval[returnval != None])

apartado_h()
# %% Apartado i
def apartado_i():
    '''Código del apartado i'''
    # Obtenemos Zs
    Z1, Z2 = get_Z(X1), get_Z(X2)

    #Y_n: np.ndarray = lambda n, aux: np.minimum(10*np.ones(np.shape(X1[0].T)[0]), 
       #                                         aux[-1])*Z2[n] 

    
    def Y_n(n,aux):
        value = np.minimum(10*np.ones(np.shape(X1[0].T)[0]), 
                                                aux[-1])
        
        value = np.where(value < 0, 0, value)

        return value*Z2[n]

    X3: np.ndarray = generar_X3(Z1, Z2, Y_n, start_val=100)
    func = lambda x: x[-1] - x[0]

    return np.mean(np.apply_along_axis(func, 0, X3))

apartado_i()
    
# %% Apartado j


# %% Apartado k


# %% Apartado l


# %% Apartado m


# %% Apartado n








'''
#Código del apartado b.
    # Obtenemos Z_1[N] a partir de X1
    Z1: np.ndarray = get_Z(X1) 
    # Obtenemos Z_2[N] a partir de X2
    Z2: np.ndarray = get_Z(X2)
    # Obtenemos Z_1[n]*Z_2[n] (Z_1[n]*Y[n]) ya que Y[n] == Z_2[n] para este 
    # apartado.
    Z_conj: np.ndarray = Z1*Z2
    # Obtenemos la cantidad de elementos de cada columna de Z_conj que son 
    # mayores que 0.
    elementos_ganadores: list = np.sum(Z_conj > 0, axis=0)
    return np.mean(elementos_ganadores)
'''