切片类型会影响到NumPy数组的可变性。

3
我使用Python创建netCDF文件。当我尝试为变量的某些部分(或切片)分配值时,根据切片的“类型”,有时可以分配值,有时则无法分配值。
我不知道原因。如果有帮助理解原因的话会非常感激。
例如:
import numpy as np
from netCDF4 import Dataset

nb_steps = 2
nb_lat = 3
nb_lon = 4

# open/create file
f = Dataset('/home/ccorbel/Desktop/test.nc', 'w', format='NETCDF3_CLASSIC')
f.createDimension('lat', nb_lat)
f.createDimension('lon', nb_lon)
f.createDimension('time', nb_steps)

# create/fill variables
variables = {}
variables['t'] = f.createVariable('temperature', 'float64', ('time', 'lat', 'lon'))
variables['t'][...] = np.zeros((nb_steps, nb_lat, nb_lon))

# "equivalent" to [0, :, ::-1]
slc  = [0, slice(None, None, None), slice(None, None, -1)]    

# "equivalent" to [0, :, :]
slc2 = [0, slice(None, None, None), slice(None, None, None)] 

# "equivalent" to [:, ::-1]
slc3 = [   slice(None, None, None), slice(None, None, -1)]

print type(variables['t'])
# type 'netCDF4.Variable'
print type(variables['t'][slc])
# type 'numpy.ndarray'
print type(variables['t'][slc][...])
# type 'numpy.ndarray'
print np.shape(variables['t'][slc])
# (3, 4)

# variables['t'][slc] = np.random.random((nb_lat, nb_lon))
# return IndexError: too many indices

variables['t'][slc][...] = np.random.random((nb_lat, nb_lon))
print '\n', variables['t'][...]

# [[[ 0.  0.  0.  0.]
#   [ 0.  0.  0.  0.]
#   [ 0.  0.  0.  0.]]
# 
#  [[ 0.  0.  0.  0.]
#   [ 0.  0.  0.  0.]
#   [ 0.  0.  0.  0.]]]

variables['t'][...] = np.zeros((nb_steps, nb_lat, nb_lon)) # reset
variables['t'][slc2] = np.random.random((nb_lat, nb_lon))[slc3]
print '\n', variables['t'][...]

# [[[ 0.17502009  0.98414122  0.89686025  0.11072791]
#   [ 0.51351626  0.09234043  0.54314083  0.937711  ]
#   [ 0.98732418  0.22714407  0.87387761  0.44653219]]

#  [[ 0.          0.          0.          0.        ]
#   [ 0.          0.          0.          0.        ]
#   [ 0.          0.          0.          0.        ]]]

variables['t'][...] = np.zeros((nb_steps, nb_lat, nb_lon)) # reset
#variables['t'][0, :, ::-1] = np.random.random((nb_lat, nb_lon)) 
# return IndexError: too many indices

variables['t'][0, :, ::-1][...] = np.random.random((nb_lat, nb_lon))
print '\n', variables['t'][...]

# [[[ 0.  0.  0.  0.]
#   [ 0.  0.  0.  0.]
#   [ 0.  0.  0.  0.]]

#  [[ 0.  0.  0.  0.]
#   [ 0.  0.  0.  0.]
#   [ 0.  0.  0.  0.]]]

variables['t'][...] = np.zeros((nb_steps, nb_lat, nb_lon)) # reset
variables['t'][0, :, :] = np.random.random((nb_lat, nb_lon))[:, ::-1]
print '\n', variables['t'][...]

# [[[ 0.61406835  0.11069783  0.28667398  0.45018246]
#   [ 0.3833354   0.98871281  0.55559104  0.60415683]
#   [ 0.75200954  0.75106639  0.11688565  0.14264615]]

#  [[ 0.          0.          0.          0.        ]
#   [ 0.          0.          0.          0.        ]
#   [ 0.          0.          0.          0.        ]]]

variables['t'][...] = np.zeros((nb_steps, nb_lat, nb_lon)) # reset
variables['t'][0, :, :] = np.random.random((nb_lat, nb_lon))[slc3]
print '\n', variables['t'][...]

# [[[ 0.09437484  0.45757906  0.81116891  0.23580254]
#   [ 0.37316425  0.06768454  0.20259876  0.42127472]
#   [ 0.78879307  0.62535419  0.08942293  0.68789143]]

#  [[ 0.          0.          0.          0.        ]
#   [ 0.          0.          0.          0.        ]
#   [ 0.          0.          0.          0.        ]]]

f.close()
1个回答

2

你的示例代码在我的机器上似乎可以工作,但我认为你可能会遇到问题,因为你在赋值语句左侧使用了多个索引。例如A[0, :, ::-1][...] = something,其中A是一个数组,这种写法很奇怪,即使它在我的机器上似乎可以工作,我也建议尽量避免使用它。如果这不能解决你的问题,你可以给我们提供一个更清晰的示例来说明你遇到的问题(最好只有一个索引操作在等号左边),或者解释一下为什么要使用两个索引操作。


我仍然不太清楚为什么,但是我也相信这是因为右侧的“双重”索引[ ][ ]。我还记得曾经在某个地方读到过用[...]进行索引会创建一个副本,这可能可以解释,因为分配可能是针对A的(切片的)副本而不是A本身。 - Christophe
你可以在这里阅读更多关于numpy索引/切片的内容:http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html但请记住,有一些黑魔法使得赋值语句左侧的索引正常工作。这种黑魔法并不适用于a[slc1][slc2]。然而,在你的情况下,你正在做a[slc1][...] = something,那么为什么不直接写成a[slc1] = something呢? - Bi Rico

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