2016-01-20 3 views
1

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

Я хотел бы получить рекомендации по оптимизации кода ниже:

#imports 
import numpy as np 
import pandas as pd 


#numpy variant 

#creation of sample matrix 
x_range = range(-180, -80, 20) 
y_range = range(5, 30, 5) 

ma = np.zeros(shape=(6,6)) 
ma[0,1:] = x_range 
ma[1:,0] = y_range 
ma[0,0] = np.nan 

# test function: 
def test_func(x, y): 
    z = (x + y)/10 

    return z 

#looping 
for y in range(1, len(ma[0,:])): 
    for x in range(1, len(ma[:,0])): 
     #print ma[0, x], ma[y, 0] 
     ma[x, y] = test_func(ma[0, x], ma[y, 0]) 

ma 
array([[ nan, -180. , -160. , -140. , -120. , -100. ], 
     [ 5. , -17.5, -17. , -16.5, -16. , -15.5], 
     [ 10. , -15.5, -15. , -14.5, -14. , -13.5], 
     [ 15. , -13.5, -13. , -12.5, -12. , -11.5], 
     [ 20. , -11.5, -11. , -10.5, -10. , -9.5], 
     [ 25. , -9.5, -9. , -8.5, -8. , -7.5]]) 

#pandas variant 

cols = x_range 
idx = y_range 

#dataframe 
df = pd.DataFrame(np.zeros(shape=(5,5)), index=idx, columns=cols) 
df.index.name = 'Y-Range' 
df.columns.name = 'X-Range' 

df 
X-Range -180 -160 -140 -120 -100 
Y-Range        
5   0  0  0  0  0 
10   0  0  0  0  0 
15   0  0  0  0  0 
20   0  0  0  0  0 
25   0  0  0  0  0 


#looping 
for col in range(0, (len(df.columns))): 
    for ind in range(0, (len(df.index))): 
     df.iloc[ind, col] = test_func(df.index[ind], df.columns[col]) 

df 
X-Range -180 -160 -140 -120 -100 
Y-Range        
5   -18 -16 -14 -12 -10 
10  -17 -15 -13 -11 -9 
15  -17 -15 -13 -11 -9 
20  -16 -14 -12 -10 -8 
25  -16 -14 -12 -10 -8 
#rounding due to console settings 

Это выше именно то, что я хотел.

Но есть ли лучший способ, более эффективный и избегающий петли?

Примечание: благодарит за ответы.

+0

Если вы внедрили запущенную версию, добавьте это в вопрос? – Divakar

+0

Что такое конечный результат? – jezrael

+0

добавлен цикл выше – DaCoEx

ответ

0

Вы можете использовать add и T:

df = pd.DataFrame(ma) 
print df 

    0 1 2 3 4 5 
0 NaN -180 -160 -140 -120 -100 
1 5 0 0 0 0 0 
2 10 0 0 0 0 0 
3 15 0 0 0 0 0 
4 20 0 0 0 0 0 
5 25 0 0 0 0 0 

df.ix[1:,1:] = (df.ix[1:,1:].add(df.ix[1:,0],axis=0) + df.ix[0,1:]).T 
print df 

    0 1 2 3 4 5 
0 NaN -180 -160 -140 -120 -100 
1 5 -175 -170 -165 -160 -155 
2 10 -155 -150 -145 -140 -135 
3 15 -135 -130 -125 -120 -115 
4 20 -115 -110 -105 -100 -95 
5 25 -95 -90 -85 -80 -75 
3

После настройки ma, вы можете заменить вложенные циклы для Векторизованного подхода путем расширения размеров одной из нарезанных частей: ma[0,1:] и добавить с другим ломтик ma[1:,0], который принесет broadcasting в игру. Будучи векторизованным подходом, это должно быть довольно быстро. Таким образом, замена петли будет выглядеть следующим образом -

ma[1:,1:] = ma[0,1:][:,None] + ma[1:,0] 

Пожалуйста, обратите внимание, что более компактный способ записи ma[0,1:][:,None] будет ma[0,1:,None].

Смежные вопросы