如何在没有警告的情况下写入结构化数组中的单个字段
How to write to single field in structured array without getting warning
如果字段包含 floats
,我正在尝试规范化结构化数组的不同字段中包含的所有数据。但是,即使我逐个遍历每个字段,我也会收到警告。
for idt, dt in enumerate(data.dtype.names):
if "float32" in data.dtype[idt].name:
stds = np.std(data[dt])
means = np.mean(data[dt])
data[dt] = (data[dt] - means) / stds
执行最后一行后弹出:
FutureWarning: Numpy has detected that you (may be) writing to an array returned
by numpy.diagonal or by selecting multiple fields in a structured
array. This code will likely break in a future numpy release --
see numpy.diagonal or arrays.indexing reference docs for details.
The quick fix is to make an explicit copy (e.g., do
arr.diagonal().copy() or arr[['f0','f1']].copy()). data[dt] = (data[dt] - means) / stds
我可以在调试器中逐行 运行 它以确保一切都符合预期,例如:
In[]: data.dtype
Out[]: dtype([('a', '<f4'), ('b', '<f4'), ('c', '<f4'), ('d', '<i4')])
In[]: dt
Out[]: 'a'
In[]: data[dt].shape
Out[]: (2000, 8)
按照警告消息中的建议,复制数组有效:
data2 = data.copy()
for idt, dt in enumerate(data2.dtype.names):
if "float32" in data2.dtype[idt].name:
stds = np.std(data2[dt])
means = np.mean(data2[dt])
data2[dt] = (data2[dt] - means) / stds
data = data2
什么是消除警告的更优雅的方法?在这种情况下副本发生了什么变化?
def foo(data):
for idt, dt in enumerate(data.dtype.names):
if "float32" in data.dtype[idt].name:
data[dt] = data[dt] + idt
In [23]: dt = np.dtype([('a', '<f4'), ('b', '<f4'), ('c', '<f4'), ('d', '<i4')])
In [24]: data = np.ones((3,), dtype=dt)
In [25]: foo(data)
In [26]: data
Out[26]:
array([( 1., 2., 3., 1), ( 1., 2., 3., 1), ( 1., 2., 3., 1)],
dtype=[('a', '<f4'), ('b', '<f4'), ('c', '<f4'), ('d', '<i4')])
这会在没有警告的情况下运行。但如果它尝试使用多字段数据选择,我会收到警告:
In [27]: data1 = data[['a','d']]
In [28]: foo(data1)
/usr/local/bin/ipython3:4: FutureWarning: Numpy has detected that you (may be) writing to an array returned
by numpy.diagonal or by selecting multiple fields in a structured
array. This code will likely break in a future numpy release --
see numpy.diagonal or arrays.indexing reference docs for details.
The quick fix is to make an explicit copy (e.g., do
arr.diagonal().copy() or arr[['f0','f1']].copy()).
import re
副本操作正常:
In [38]: data1 = data[['d','a']].copy()
In [39]: foo(data1)
In [40]: data1
Out[40]:
array([(1, 2.), (1, 2.), (1, 2.)],
dtype=[('d', '<i4'), ('a', '<f4')])
(接下来,我将尝试使用 h5py
保存和检索此数组,看看是否有所不同。)
与h5py
、
d1 = f['data']
foo(d1) # operate directly on the dataset
data1 = d1[:]; foo(data1) # operate on a copy
data1 = d1[:,'a','b'] # also a copy
我无法使用 h5py
个数据集重现警告。
也可以抑制警告。但首先你需要清楚地理解警告的含义和任何后果。
如果字段包含 floats
,我正在尝试规范化结构化数组的不同字段中包含的所有数据。但是,即使我逐个遍历每个字段,我也会收到警告。
for idt, dt in enumerate(data.dtype.names):
if "float32" in data.dtype[idt].name:
stds = np.std(data[dt])
means = np.mean(data[dt])
data[dt] = (data[dt] - means) / stds
执行最后一行后弹出:
FutureWarning: Numpy has detected that you (may be) writing to an array returned by numpy.diagonal or by selecting multiple fields in a structured array. This code will likely break in a future numpy release -- see numpy.diagonal or arrays.indexing reference docs for details. The quick fix is to make an explicit copy (e.g., do arr.diagonal().copy() or arr[['f0','f1']].copy()). data[dt] = (data[dt] - means) / stds
我可以在调试器中逐行 运行 它以确保一切都符合预期,例如:
In[]: data.dtype
Out[]: dtype([('a', '<f4'), ('b', '<f4'), ('c', '<f4'), ('d', '<i4')])
In[]: dt
Out[]: 'a'
In[]: data[dt].shape
Out[]: (2000, 8)
按照警告消息中的建议,复制数组有效:
data2 = data.copy()
for idt, dt in enumerate(data2.dtype.names):
if "float32" in data2.dtype[idt].name:
stds = np.std(data2[dt])
means = np.mean(data2[dt])
data2[dt] = (data2[dt] - means) / stds
data = data2
什么是消除警告的更优雅的方法?在这种情况下副本发生了什么变化?
def foo(data):
for idt, dt in enumerate(data.dtype.names):
if "float32" in data.dtype[idt].name:
data[dt] = data[dt] + idt
In [23]: dt = np.dtype([('a', '<f4'), ('b', '<f4'), ('c', '<f4'), ('d', '<i4')])
In [24]: data = np.ones((3,), dtype=dt)
In [25]: foo(data)
In [26]: data
Out[26]:
array([( 1., 2., 3., 1), ( 1., 2., 3., 1), ( 1., 2., 3., 1)],
dtype=[('a', '<f4'), ('b', '<f4'), ('c', '<f4'), ('d', '<i4')])
这会在没有警告的情况下运行。但如果它尝试使用多字段数据选择,我会收到警告:
In [27]: data1 = data[['a','d']]
In [28]: foo(data1)
/usr/local/bin/ipython3:4: FutureWarning: Numpy has detected that you (may be) writing to an array returned
by numpy.diagonal or by selecting multiple fields in a structured
array. This code will likely break in a future numpy release --
see numpy.diagonal or arrays.indexing reference docs for details.
The quick fix is to make an explicit copy (e.g., do
arr.diagonal().copy() or arr[['f0','f1']].copy()).
import re
副本操作正常:
In [38]: data1 = data[['d','a']].copy()
In [39]: foo(data1)
In [40]: data1
Out[40]:
array([(1, 2.), (1, 2.), (1, 2.)],
dtype=[('d', '<i4'), ('a', '<f4')])
(接下来,我将尝试使用 h5py
保存和检索此数组,看看是否有所不同。)
与h5py
、
d1 = f['data']
foo(d1) # operate directly on the dataset
data1 = d1[:]; foo(data1) # operate on a copy
data1 = d1[:,'a','b'] # also a copy
我无法使用 h5py
个数据集重现警告。
也可以抑制警告。但首先你需要清楚地理解警告的含义和任何后果。