Reputation: 677
Given three 1D numpy arrays and three 2D numpy arrays:
1D numpy arrays:
V = [ V_a V_b]
EL = [EL_a EL_b]
E0 = [E0_a E0_b]
2D numpy arrays:
T = [[ T_1a T_2a T_3a T_4a ] [ T_1b T_2b T_3b T_4b ]]
ET = [[ ET_1a ET_2a ET_3a ET_4a] [ ET_1b ET_2b ET_3b ET_4b]]
TS = [[ TS_1a TS_2a TS_3a TS_4a] [ TS_1b TS_2b TS_3b TS_4b]]
I would like to create four files:
T_1.dat
T_2.dat
T_3.dat
T_4.dat
with the following info:
T_1.dat | T_2.dat | T_3.dat | T_4.dat
----------------------------------------------------------------------------------------------------------------------------------------
VOLUME: F: | VOLUME: F: | VOLUME: F: | VOLUME: F:
| | |
V_a F(V_a, T_1) | V_a F(V_a, T_2) | V_a F(V_a, T_3) | V_a F(V_a, T_4)
V_b F(V_b, T_1) | V_b F(V_b, T_2) | V_b F(V_b, T_3) | V_b F(V_b, T_4)
where F
is calculated as:
F(V_a, T_1) = EL_a + E0_a + ET_1a - TS_1a
F(V_b, T_1) = EL_b + E0_b + ET_1b - TS_1b
... and so on ...
The following nested loops over all these variables:
import numpy as np
V = np.array([ 226.331804, 228.817957])
EL = np.array([-3765.00423366, -3765.0072724 ])
E0 = np.array([ 0.07389338, 0.07347015])
T = np.array([[ 10., 30.1, 50.2, 70.3],
[ 10., 30.1, 50.2, 70.3]])
ET = np.array([[ 2.86370000e-08, 3.59345110e-05, 2.47740762e-04, 7.11121913e-04],
[ 4.16950000e-08, 4.07323670e-05, 2.66315355e-04, 7.47534260e-04]])
TS = np.array([[ 3.14910000e-08, 4.50715970e-05, 3.33253672e-04, 1.00376212e-03],
[ 4.60170000e-08, 5.14553150e-05, 3.61155871e-04, 1.06376830e-03]])
rows = ET.shape[0]
cols = ET.shape[1]
F_all = []
for x, indx_EL, indx_E0 in zip(range(0, rows), range(len(EL)), range(len(E0))):
aux = []
for y in range(0, cols):
F = EL[indx_EL] + E0[indx_E0] + ET[x,y] + TS[x,y]
print F
aux.append(F)
F_all.append(aux)
F_all = np.array(F_all)
print ' F_all = ', F_all
The result is the following:
F_all = [[-3764.93034022 -3764.93025927 -3764.92975929 -3764.9286254 ]
[-3764.93380216 -3764.93371006 -3764.93317478 -3764.93199095]]
If I manually calculate the first element I see it does not coincide with the calculated one.
F(V_a, T_1) = EL_a + E0_a + ET_1a - TS_1a
= -3765.00423366 + 0.07389338 + 2.86370000e-08 - 3.14910000e-08
= -3764.93034028285
I cannot see the reason why is the nested loop failing? In addition, is this the best way to generate the above T_i.dat
files ?
Upvotes: 0
Views: 516
Reputation: 677
Thanks to @Piinthesky answer, it should be -TS[x, y]
in the inner loop:
F_all = []
for x, indx_EL, indx_E0 in zip(range(0, rows), range(len(EL)), range(len(E0))):
aux = []
for y in range(0, cols):
F = EL[indx_EL] + E0[indx_E0] + ET[x,y] - TS[x,y]
aux.append(F)
F_all.append(aux)
F_all = np.array(F_all)
print ' F_all looping = ', F_all
which yields:
F_all looping = [[-3764.93034028 -3764.93034941 -3764.93042579 -3764.93063291] [-3764.93380225 -3764.93381297 -3764.93389709 -3764.93411848]]
It is very interesting the broadcasting approach:
print 'EL + E0 = ', EL + E0
print 'np.shape(EL + E0) = ', np.shape(EL + E0)
EL + E0 = [-3764.93034027 -3764.93380225]
np.shape(EL + E0) = (2,)
print 'ET - TS = ', ET - TS
print 'np.shape(ET - TS) = ', np.shape(ET - TS)
ET - TS = [[ -2.85400000e-09 -9.13708600e-06 -8.55129100e-05 -2.92640207e-04] [ -4.32200000e-09 -1.07229480e-05 -9.48405160e-05 -3.16234040e-04]]
np.shape(ET - TS) = (2, 4)
In order to perform (EL + E0) + (ET - TS)
through broadcasting, since (ET - TS)
is of shape (2, 4)
and (EL + E0)
of shape (2,)
, we would have to transform (EL + E0)
to be of shape (2, 1)
. Currently it is shape (2,)
. In
order to create an axis with length 1, @Piinthesky 's None
approach is very suitable:
print '(EL + E0)[:, None] = ', (EL + E0)[:, None]
print 'np.shape((EL + E0)[:, None]) = ', np.shape((EL + E0)[:, None])
(EL + E0)[:, None] = [[-3764.93034027] [-3764.93380225]]
np.shape((EL + E0)[:, None]) = (2, 1)
So, now, we can broadcast:
F_all = (EL + E0)[:, None] + (ET - TS)
print ' F_all broadcasting = ', F_all
F_all broadcasting = [[-3764.93034028 -3764.93034941 -3764.93042579 -3764.93063291] [-3764.93380225 -3764.93381297 -3764.93389709 -3764.93411848]]
which yields the same result as my F_all_looping
approach.
Upvotes: 0
Reputation: 12410
You are making your life harder than necessary by looping over the index. I heard quite often here on SO "If you use numpy
with loops you are probably doing it wrong". And it is true. You can instead use numpy
broadcasting:
F_all = (EL + E0)[:, None] + (ET - TS)
Et voila.
P.S.: I am not going to do your debugging, but shouldn't it be -TS[x, y]
in your inner loop?
Upvotes: 1