轴1的长度为4,索引4超出了范围。带有双重求和的代码。

4

你好,我有以下函数会产生越界错误:

import numpy as np
import pylab as plt
import scipy
import math
import sympy as sy


T = sy.Symbol('T')
rho = sy.Symbol('rho')


g_T   = [1,T,T**2,T*sy.log(T),T**2*sy.log(T)]
g_rho  = [1,rho,rho**2,rho*sy.log(rho),rho**2*sy.log(rho)]

g_T_np = np.asarray(g_T)
g_rho_np = np.asarray(g_rho)


c = np.loadtxt("c_test.txt")


def F(T,rho):
    ret = 0
    for n in xrange(1,5):
        for m in xrange(1,6):
            inner= c[n,m]*g_T_np*g_rho_np
        ret += inner
    return ret

print F(T,rho)

文件 .txt 的格式如下:

-0.529586   -0.000208559    -3.36563E-09    2.29441E-05 
2.22722E-06 -0.00014526 -2.48888E-09    1.89488E-05 
-6.26662E-05    0.000421028 6.17407E-09 -5.14488E-05    
0.09977346  -0.000622051    -8.56485E-09    7.49956E-05 
-0.01437627 -9.86754E-05    -1.59808E-09    1.22574E-05

完整的错误信息如下:
Traceback (most recent call last):File "EOS_test.py", line 38, in print F(T,rho) File "EOS_test.py", line 31, in F inner=c[n,m]*g_T_np*g_rho_np IndexError: index 4 is out of bounds for axis 1 with size 4
我该如何解决这个错误?

嗨,Shaun,欢迎来到 Stack Overflow。我已修复您的格式。作为将来的参考,代码(和想要看起来像代码的东西)只需至少缩进 4 个空格即可格式化。您还可以选择代码并单击编辑器中 looks like {} 的按钮。 - Scott Mermelstein
你能否发布确切的错误信息,并指出它发生在哪一行? - Scott Mermelstein
@ScottMermelstein:非常感谢您的格式化,看起来好多了!还有感谢您提供的如何在未来处理它的信息。 错误看起来像这样 \ Traceback(最近的调用最后):文件“EOS_test.py”,第38行,在<module>中: print F(T,rho) 文件“EOS_test.py”,第31行,在F中: inner = c [n,m] * g_T_np * g_rho_np IndexError:索引4超出了大小为4的轴1的范围 - Shaun
@ScottMermelstein:看起来仍然很糟糕...这在评论中也可以工作吗?:) 抱歉 - Shaun
注释具有有限的格式化功能。(单击注释框旁边的帮助以查看。)尤其是与问题相关的信息,最好的选择是编辑问题,提供额外的信息。即使我已经回答了,请这样做。 :-) - Scott Mermelstein
2个回答

5
Numpy使用基于0的索引。从你所看到的情况来看,你正在将数组从第1个位置(即第2个位置)到第4个位置进行索引,这当然超出了你正在处理的数组的范围。对于第二个轴也是如此。其次,你弄混了轴:
- 第一个轴(0)是所选行的索引(0到5) - 第二个轴是列的索引,即行内的值(索引为0到4)
这应该可以工作:
def F(T,rho):
    ret = 0
    for n in range(5):
        for m in range(4):
            inner= c[n,m]*g_T_np*g_rho_np
        ret += inner
    return ret

0

你的问题在于设置了你的xrange

Python列表(和np数组)是从0开始索引的,因此你不需要使用索引[1,2,3,4,5]和[1,2,3,4,5,6],而是需要使用[0,1,2,3,4]和[0,1,2,3,4,5][0,1,2,3]和[0,1,2,3,4]。

按照以下方式设置你的for循环可以解决你的问题:

for n in xrange(0,4):
    for m in xrange(0,5):

或者,您可以利用xrange的默认起始点,只需列出一个参数:

for n in xrange(4):
    for m in xrange(5):

此外,为了实现更符合 Python 风格的解决方案,可以尝试使用 ndarray 迭代器,而不是嵌套 for 循环。文档提供了以下示例:
it = np.nditer(c, flags=['f_index'])
while not it.finished:
    inner= c[it[0]]*g_T_np*g_rho_np
    ret += inner
    it.iternext()

这样做可以避免需要知道导入数组的大小的整个问题,因此更加健壮。

编辑:正如pdowling在他的答案中提到的那样,范围数字应该是4和5。我之前在我的回答中留下了5和6,现在已经更正了。


对于n在0到4的范围内,对于m在0到5的范围内:尝试过之前的方法但没有成功。其他选项也不行。我认为@pdowling是正确的,因为当我交换了轴时它就起作用了。但还是感谢您的快速回复。 - Shaun
如果您发现他的信息有帮助,请点赞。 (您可以点赞或反对任何答案。)如果它解决了您的问题,您应该点击复选标记。请参阅http://stackoverflow.com/help/someone-answers - Scott Mermelstein
慢慢开始理解了!:) 非常感谢你的耐心。 - Shaun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接