简体   繁体   中英

Python script returns an array instead of a single value

I've got a python script using numpy that should take an image and perform a few calculations before returning a single value. When I execute each line individually, it works as expected. When I put it all together in a .py script and run it from the command line or within Canopy, it returns an array.

I've modified the code slightly to not require the usual image input, and the result is the same:

import numpy as np

# Instead of loading an image, generate a test case (w or wo structured noise)
roi = np.random.poisson(38,(256,256));
blob = np.random.poisson(5,(128,128));
roi[64:192,64:192] = roi[64:192,64:192]+blob;
# Load the other variables if necessary (i.e., no DICOM to load)
[xDim,yDim] = [512,512];
roiLength = xDim/2;
pix = 1.18958;

# Declare memory for the FFTs
sizeFFT = xDim;
NPS2D = np.zeros((sizeFFT,sizeFFT)); # declare memory for fft results
fftslice = np.zeros((sizeFFT,sizeFFT));

# Set the dimension of the ROI and pull the pixel size. This will be
# used for the scaling factor in the 2D NPS. 
deltaX = pix;
deltaY = pix;
scaleFactor = (deltaX/roiLength)*(deltaY/roiLength);

# Calculate the NPS
roiMean = np.mean(roi);
fftslice = np.fft.fft2((roi-roiMean),s=[sizeFFT,sizeFFT]); 
NPS2D = scaleFactor*np.fft.fftshift(np.multiply(fftslice,np.conj(fftslice)));
NPS2D = NPS2D.real;

# Subtract the white noise from the NPS to get the structured NPS
stNPS = NPS2D - roiMean*deltaX*deltaY;

# Calculate SNI
SNI=sum(stNPS)/sum(NPS2D);

# Display the result
print SNI;

The result if I execute each line is 0.107213670449 (or similar, since it's regenerating a random array each time). If I run the script from the command line using python foo.py or click the play button in Canopy, the result is a 512 length array [4.64940089e-03 ... -4.59789051e-02 -7.15113682e-02] , where I've manually removed 509 entries.

Any thoughts? Am I missing something obvious?

SNI=sum(stNPS)/sum(NPS2D)

Does summation across columns in default python way. So, you get an array of length 512

Instead try sum from numpy

SNI=stNPS.sum()/NPS2D.sum()

Using the builtin sum function is different than using numpy.sum or the sum method of an array.

For >1d arrays, python's sum will give a very different result:

In [1]: import numpy as np

In [2]: x = np.arange(100).reshape(10, 10)

In [3]: x
Out[3]:
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
       [40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
       [50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
       [60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
       [70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
       [80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
       [90, 91, 92, 93, 94, 95, 96, 97, 98, 99]])

In [4]: sum(x)
Out[4]: array([450, 460, 470, 480, 490, 500, 510, 520, 530, 540])

In [5]: x.sum()
Out[5]: 4950

In [6]: np.sum(x)
Out[6]: 4950

This is because python's sum is basically summing a for loop over the object.

Looping over a >1d array will return slices along the first axis. Eg

In [7]: for item in x:
   ...:     print item
   ...:
[0 1 2 3 4 5 6 7 8 9]
[10 11 12 13 14 15 16 17 18 19]
[20 21 22 23 24 25 26 27 28 29]
[30 31 32 33 34 35 36 37 38 39]
[40 41 42 43 44 45 46 47 48 49]
[50 51 52 53 54 55 56 57 58 59]
[60 61 62 63 64 65 66 67 68 69]
[70 71 72 73 74 75 76 77 78 79]
[80 81 82 83 84 85 86 87 88 89]
[90 91 92 93 94 95 96 97 98 99]

In this case, Python's sum is effectively giving you the sums of the columns (ie row1 + row2 + row3 ... )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM