Python: создайте многомерный массив, поместив одномерный массив в цикл - PullRequest
1 голос
/ 19 апреля 2019

Прошло 2 дня с тех пор, как я работал над этой проблемой, но не могу прорваться.В приведенном ниже коде внутренний цикл for создает pathwiseminS массив (252,) при каждом запуске.

То, что я хочу, это когда этот цикл заканчивается, чтобы сложить его в другой массив (строка за строкой или столбец за столбцом, все, что работает!).В итоге создаем многомерный массив с именем total, который должен быть либо (200,252), либо (252,200).

Я пробовал np.concatenate, 'np.vstack и т. Д., Но не могу получить это право.

class pricing_lookback:
def __init__(self, spot, rate, sigma, time, sims, steps):
    self.spot = spot
    self.rate = rate
    self.sigma = sigma
    self.time = time
    self.sims = sims
    self.steps = steps
    self.dt = self.time / self.steps

def call_floatingstrike(self):

    simulationS = np.array([])
    simulationSt = np.array([])
    call2 = np.array([])
    total = np.array([])
    # total = np.empty(shape=[self.steps, self.sims])
    # total = np.empty(shape=self.steps,).reshape(self.steps)
    for j in range(self.sims):
        sT = self.spot
        pathwiseminS = np.array([])
        for i in range(self.steps):
            phi = np.random.normal()
            sT *= np.exp(
                (self.rate - 0.5 * self.sigma * self.sigma) * self.dt + self.sigma * phi * np.sqrt(self.dt))
            pathwiseminS = np.append(pathwiseminS, sT)
            total = pathwiseminS.copy()

        # print(np.shape(pathwiseminS))
        total = np.append([total],[total], axis=0)
        # np.hstack((total,pathwiseminS.transpose()))
        # print(np.size(b), np.shape(b))
        call2 = np.append(call2, max(pathwiseminS[self.steps - 1] - self.spot, 0))
        # print (pathwiseminS[self.steps-1])
        # print(call2)
        simulationSt = np.append(simulationSt, pathwiseminS[self.steps - 1])
        simulationS = np.append(simulationS, min(pathwiseminS))
    # print(b)
    call = max(np.average(simulationSt) - np.average(simulationS), 0)
    return call, total  # ,call2,

Если я печатаю total, в конце я получаю матрицу (2,252)

Ответы [ 2 ]

0 голосов
/ 19 апреля 2019

Это типичный способ построения массива из списков списков:

In [127]: alist = [] 
     ...: for i in range(3): 
     ...:     sublist = [] 
     ...:     for j in range(4): 
     ...:         sublist.append(i*10+j) 
     ...:     alist.append(sublist) 
     ...:                                                                            
In [128]: alist                                                                      
Out[128]: [[0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23]]
In [129]: np.array(alist)                                                            
Out[129]: 
array([[ 0,  1,  2,  3],
       [10, 11, 12, 13],
       [20, 21, 22, 23]])

Я пытался повторить подход добавления списка с concatenates, но продолжал сталкиваться с ошибками вроде

ValueError: all the input arrays must have same number of dimensions
ValueError: all the input array dimensions except for the concatenation axis must match exactly

In [130]: arr = np.zeros((0,4), int) 
     ...: for i in range(3): 
     ...:     arr1 = np.zeros((0),int) 
     ...:     for j in range(4): 
     ...:         arr1 = np.concatenate((arr1, np.array([i*10+j]))) 
     ...:     arr = np.concatenate((arr, arr1), axis=0) 

Я мог бы в конечном итоге получить правильные размеры, но это не стоит моего времени.

Самый быстрый, не итеративный подход - это что-то вроде:

In [133]: np.arange(4)+10*np.arange(3)[:,None]                                       
Out[133]: 
array([[ 0,  1,  2,  3],
       [10, 11, 12, 13],
       [20, 21, 22, 23]])

Если вы должны выполнить итерацию, этопроще создать пустой массив правильного размера и присвоить значения:

In [135]: arr = np.zeros((3,4),int) 
     ...: for i in range(3): 
     ...:     for j in range(4): 
     ...:         arr[i,j] = 10*i+j 
     ...: arr                                                                        
Out[135]: 
array([[ 0,  1,  2,  3],
       [10, 11, 12, 13],
       [20, 21, 22, 23]])

Этот последний подход имеет скорость, сравнимую с добавлением в список.


Очищено concatenate версия.

arr будет 2d, (n, 4), на каждом шаге.

arr1 равно 1d, (m,), на каждом шаге;его нужно расширить до 2d, чтобы объединить с arr.

In [158]: arr = np.zeros((0,4), int) 
     ...: for i in range(3): 
     ...:     arr1 = np.zeros((0,),int) 
     ...:     for j in range(4): 
     ...:         arr1 = np.concatenate((arr1, np.array([i*10+j]))) 
     ...:     arr = np.concatenate((arr, arr1[None,:]), axis=0) 
     ...:                                                                            
In [159]: arr                                                                        
Out[159]: 
array([[ 0,  1,  2,  3],
       [10, 11, 12, 13],
       [20, 21, 22, 23]])

np.append - это всего лишь concatenate, что гарантирует, что входы по крайней мере 1d.Таким образом, мы можем использовать его во внутреннем цикле.np.vstack гарантирует, что его входы 2d, поэтому мы можем использовать его во внешнем цикле.Они просто скрывают детали;они не меняют скорость.

In [161]: arr = np.zeros((0,4), int) 
     ...: for i in range(3): 
     ...:     arr1 = np.zeros((0,),int) 
     ...:     for j in range(4): 
     ...:         arr1 = np.append(arr1, i*10+j) 
     ...:     arr = np.vstack((arr, arr1)) 
0 голосов
/ 19 апреля 2019

Мой друг решил это: в основном изменил массив при возврате. Также ниже приведен бесплатный код для определения цены вызова с плавающей запятой.

class pricing_lookback:
def __init__(self, spot, rate, sigma, time, sims, steps):
    self.spot = spot
    self.rate = rate
    self.sigma = sigma
    self.time = time
    self.sims = sims
    self.steps = steps
    self.dt = self.time / self.steps

def call_floatingstrike(self):

    simulationS = np.array([])
    simulationSt = np.array([])
    call2 = np.array([])
    total = np.array([])
    for j in range(self.sims):
        sT = self.spot
        pathwiseminS = np.array([])
        for i in range(self.steps):
            phi = np.random.normal()
            sT *= np.exp(
                (self.rate - 0.5 * self.sigma * self.sigma) * self.dt + self.sigma * phi * np.sqrt(self.dt))
            pathwiseminS = np.append(pathwiseminS, sT)

        total = np.concatenate((total, pathwiseminS), axis=0)#This is add everything to one row
        call2 = np.append(call2, max(pathwiseminS[self.steps - 1] - self.spot, 0))
        simulationSt = np.append(simulationSt, pathwiseminS[self.steps - 1])
        simulationS = np.append(simulationS, min(pathwiseminS))

    call = max(np.average(simulationSt) - np.average(simulationS), 0)
    return call, total.reshape(self.sims, self.steps)# This transforms it to expected matrix
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...