【问题标题】:Nested loops over 2D and 1D numpy arrays saving into files2D 和 1D numpy 数组上的嵌套循环保存到文件中
【发布时间】:2018-06-23 10:52:03
【问题描述】:

问题陈述:

给定三个 1D numpy 数组和三个 2D numpy 数组:

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]]

我想创建四个文件:

T_1.dat
T_2.dat
T_3.dat
T_4.dat

带有以下信息:

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)

其中F 计算为:

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

...等等...

我的尝试:

以下所有这些变量的嵌套循环:

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

结果如下:

 F_all =  [[-3764.93034022 -3764.93025927 -3764.92975929 -3764.9286254 ]
 [-3764.93380216 -3764.93371006 -3764.93317478 -3764.93199095]]

如果我手动计算第一个元素,我看到它与计算的元素不一致。

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

我看不到嵌套循环失败的原因?另外,这是生成上述T_i.dat文件的最佳方式吗?

【问题讨论】:

  • @Piinthesky 请取消删除您的答案,以便我接受。你的广播方式很有趣;您还在内部循环中检测到 -TS[x, y] 上的错误,因此您的答案必须被接受。

标签: python numpy for-loop multidimensional-array nested


【解决方案1】:

感谢@Piinthesky 的回答,内部循环中应该是-TS[x, y]

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

产生:

F_all 循环 = [[-3764.93034028 -3764.93034941 -3764.93042579 -3764.93063291] [-3764.93380225 -3764.93381297 -3764.93389709 -3764.93411848]]

广播方式很有意思:

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)

为了通过广播执行(EL + E0) + (ET - TS),因为(ET - TS) 的形状为(2, 4)(EL + E0) 的形状为(2,),我们必须将(EL + E0) 的形状转换为(2, 1)。目前是形状(2,)。在 为了创建长度为 1 的轴,@Piinthesky 的 None 方法非常适合:

print '(EL + E0)[:, None] = ', (EL + E0)[:, None]
print 'np.shape((EL + E0)[:, None]) = ', np.shape((EL + E0)[:, None])

(EL + E0)[:, 无] = [[-3764.93034027] [-3764.93380225]]

np.shape((EL + E0)[:, None]) = (2, 1)

所以,现在,我们可以广播了:

F_all = (EL + E0)[:, None] + (ET - TS)
print ' F_all broadcasting = ', F_all

F_all 广播 = [[-3764.93034028 -3764.93034941 -3764.93042579 -3764.93063291] [-3764.93380225 -3764.93381297 -3764.93389709 -3764.93411848]]

这与我的 F_all_looping 方法产生的结果相同。

【讨论】:

    【解决方案2】:

    循环遍历索引会使您的生活变得比必要的更加艰难。我经常在这里听到“如果你使用 numpy 和循环,你可能做错了”。这是真的。你可以改用numpy broadcasting:

    F_all = (EL + E0)[:, None] + (ET - TS)
    

    等等。

    P.S.:我不打算做你的调试,但你的内循环不应该是-TS[x, y]吗?

    【讨论】:

    • 感谢您的回答。在我的回答中,我表明我的 F_all_looping 方法产生的结果与您的广播方法相同。
    • 广播的优点是它利用数组上的向量化操作,即numpy广播比等效的 Python 循环快得多。而且,它看起来很整洁。
    猜你喜欢
    • 2018-06-24
    • 1970-01-01
    • 1970-01-01
    • 2021-01-28
    • 1970-01-01
    • 2013-04-15
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多