Как итеративно добавить фрейм данных, представляющий пространственный сценарий x и y, используя вложенные циклы for?

Я пытаюсь создать фрейм данных для представления топографического выражения. До сих пор я написал пару циклов for, которые можно использовать по отдельности для выражения осей x и y, особенно в формах,

a = []   
for x in range(1,i,1):
    x1 = some function of x
    x2 = another function of x 
    a.append({'a':x, 'b':x1, 'c': x2})
xaxis = pd.DataFrame(a)

для оси x и,

a = []
for y in range(-j, j, 1):
    y1 = some function of y   
    a.append({'a':y,'b':y1})
yaxis = pd.DataFrame(a)

для оси у.

Все достаточно просто и работает нормально, однако...

Я хочу расширить это так, чтобы цикл оси y повторялся с каждой итерацией цикла оси x, а функция y1 зависела от параметров цикла оси x. Я захожу так далеко,

a = []   
for x in range(1,i,1):
    x1 = some function of x
    x2 = another function of x 
    for y in range(-j, j, 1):
        y1 = some function of y that calls x2
    a.append({

и я в тупике.

Результат, который мне нужен, по сути, таков:

x    x1      x2     y    y1       
     x1(1)   x2(1)  -j   y1(1,-j)  
1    x1(1)   x2(1)  0    y1(1,0)   
     x1(1)   x2(1)  j    y1(1,j)      
     x1(2)   x2(2)  -j   y1(2,-j)  
2    x1(2)   x2(2)  0    y1(2,0)   
     x1(2)   x2(2)  j    y1(2,j)  
....

и так далее до x = i.

Конечное желание состоит в том, чтобы иметь данные, которые можно представить в виде двумерной гистограммы.

Если есть лучший способ сделать это, пожалуйста, дайте мне знать, это единственный способ, который я могу сейчас придумать, чтобы получить результат, который мне нужен.

edit: Оказывается, это можно сделать довольно эффективно, используя массивы numpy. Это общее выражение того, как я достиг этой цели в конце концов,

y1 = lambda x,y: f(x,y)
np.array( [ [ y1(x,y) for x in xrange(1,i,1)] for y in xrange(-j,j,1)] )

person Monkone    schedule 15.06.2018    source источник


Ответы (1)


Вы должны найти векторизованную версию ваших функций. Это может быть достигнуто (на мгновение) с помощью нескольких векторизованных функций numpy или с помощью numpy.vectorized(). Взгляните на этот пример:

import numpy as np

def f1(x):
    return x**2

def f2(x):
    return np.abs(x)

def f3(x,y):
    return x**2 + y**2

i = 3 ; j = 2
x = np.arange(1,i,1)
y = np.arange(-j,j,1)

# Now build cartesian product of x and y
xy = np.array([np.tile(x, len(y)), np.repeat(y, len(x))])
xy
array([[ 1,  2,  1,  2,  1,  2,  1,  2],
       [-2, -2, -1, -1,  0,  0,  1,  1]])

x1 = f1(xy[0,])
x1
array([1, 4, 1, 4, 1, 4, 1, 4], dtype=int32)

x2 = f2(xy[0,])
x2
array([1, 2, 1, 2, 1, 2, 1, 2])

y1 = f3(xy[0,], xy[1,])
y1
array([5, 8, 2, 5, 1, 4, 2, 5], dtype=int32)
person Neroksi    schedule 15.06.2018
comment
Привет, спасибо за ответ! Функции — это просто уравнения, вот они: x1 = np.exp(-1,55*x) + 1,2*np.exp(-1,27629*x ** (1,0/2)) + 0,96*np.exp(-2,07668* x ** (1,0/3)) x2 = 98,508*x ** 0,961 y1 = x1*2e6*np.exp(((-y ** 2)/(x2 ** 2))/2) - person Monkone; 15.06.2018
comment
Как FYI, у меня был небольшой успех в том, что я пытаюсь сделать с помощью groupby, однако я сталкиваюсь с проблемами использования памяти задолго до завершения. Этот кадр данных, к которому я стремлюсь, будет иметь 400 миллионов строк, что кажется слишком большим для панд. - person Monkone; 15.06.2018
comment
Поскольку ваши функции представляют собой просто комбинацию функций numpy, они уже векторизованы, и приведенное выше решение должно работать (не забудьте адаптировать имена и формат переменных). Для ваших проблем с памятью технически Pandas имеет никаких ограничений, и только ваш жесткий диск будет ограничивать вас. Если необходимо, откройте еще один вопрос, так как задавать много вопросов под одним и тем же постом не рекомендуется. - person Neroksi; 15.06.2018
comment
Хорошо, я задавался вопросом, было ли дело в том, что все уже было векторизовано, но теперь я знаю. Спасибо за помощь :) Попробую на лучшей машине и посмотрю, как пойдет. - person Monkone; 15.06.2018
comment
Привет еще раз, это не совсем то, что я хотел. Допустим, я ввожу диапазон (1, 11, 1) для x и (-5,5,1) для y. Я получаю серию из 10 значений для y1, тогда как я ищу все 100 точек, которые были бы в матрице 10 х 10 - person Monkone; 15.06.2018
comment
Я отредактировал предложенное решение. Протестируйте и оставьте отзыв - person Neroksi; 15.06.2018
comment
Эй, мужик, еще раз спасибо за предложение. Это не совсем то, что мне нужно, но вы указали мне правильное направление, и после множества проб и ошибок я понял, как получить то, что мне нужно. Я выложу свое решение. - person Monkone; 16.06.2018