我一直在玩Scipy的内联工具(通过编织)以获得乐趣,但我遇到了一些麻烦。我的C生锈了,我觉得我错过了一些简单的东西。
以下功能旨在采用3D float32 numpy数组。我正在使用大量网格化大气数据,但这适用于任何3D阵列。然后,这将获取网格并获得跨越轴i的算术平均值,对于每个点j,k(即,如果i是时间轴,则j和k是纬度/经度,那么我对于每个网格点对时间进行平均)。
我希望我的代码正在执行此操作并避免使用nunky NaN(我相信isnan()适用于内联C / C ++ ......?)。但是,无论是否这样做,我都无法在没有错误的情况下编译代码,例如:
tools.py: In function ‘PyObject* compiled_func(PyObject*, PyObject*)’:
tools.py:93:45: error: invalid types ‘float[int]’ for array subscript
tools.py:95:51: error: invalid types ‘float[int]’ for array subscript
tools.py: In function ‘PyObject* compiled_func(PyObject*, PyObject*)’:
tools.py:93:45: error: invalid types ‘float[int]’ for array subscript
tools.py:95:51: error: invalid types ‘float[int]’ for array subscript
我认为我正在宣布和正确地进行初始化,所以也许某些东西没有按照我认为的方式传递给编织?如果有人可以帮我解决这个问题,我会很高兴。这是功能:
from scipy.weave import inline
def foo(x):
xi = np.shape(x)[0]
xj = np.shape(x)[1]
xk = np.shape(x)[2]
code = """
#line 87 "tools.py"
int n;
float out[xj][xk];
for (int k = 0; k < xk; k++) {
for (int j = 0; j < xj; j++) {
n = 0;
for (int i = 0; i < xi; i++) {
if (!isnan(x[i][j][k])) {
n += 1;
out[j][k] += x[i][j][k];
}
}
out[j][k] = out[j][k]/n;
}
}
return_val = out;
"""
awesomeness = inline(code, ['x', 'xi', 'xj', 'xk'], compiler = 'gcc')
return(awesomeness)
答案 0 :(得分:1)
您可以先在python中创建out数组,然后将其传递给C ++。在C ++中,您可以通过Nx [0],Nx [1],Nx [2]得到x的形状。您可以使用为数组定义的宏来访问它的元素。例如:X3(k,j,i)与python中的x [k,j,i]相同,而OUT2(j,i)与python中的out [j,i]相同。您可以查看自动创建的C ++代码,以了解可用于数组的变量和宏。获取C ++代码的文件夹:
from scipy import weave
print weave.catalog.default_dir()
我的编译器不支持isnan(),所以我使用tmp == tmp来检查它。
# -*- coding: utf-8 -*-
import scipy.weave as weave
import numpy as np
def foo(x):
out = np.zeros(x.shape[1:])
code = """
int i,j,k,n;
for(i=0;i<Nx[2];i++)
{
for(j=0;j<Nx[1];j++)
{
n = 0;
for(k=0;k<Nx[0];k++)
{
double tmp = X3(k,j,i);
if(tmp == tmp) // if isnan() is not available
{
OUT2(j,i) += tmp;
n++;
}
}
OUT2(j,i) /= n;
}
}
"""
weave.inline(code, ["x","out"], headers=["<math.h>"], compiler="gcc")
return out
np.random.seed(0)
x = np.random.rand(3,4,5)
x[0,0,0] = np.nan
mx = np.ma.array(x, mask=np.isnan(x))
avg1 = foo(x)
avg2 = np.ma.average(mx, axis=0)
print np.all(avg1 == avg2)
您还可以使用blitz converter在C ++中访问数组。有关详细信息,请尝试使用google:weave.converters.blitz
答案 1 :(得分:0)
C不支持像[xj] [xk]那样的动态数组大小调整。你要么必须硬编码大小,要么使用malloc或Weave支持的东西来动态分配数据。