I am trying to normalize all data contained in different fields of my structured array if the field contains floats
. However, even though I am looping through each field one-by-one I am receiving a warning.
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
After executing the last line this pops up:
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
I can run it line by line in a debugger to make sure everything is as expected, e.g.:
In[]: data.dtype
Out[]: dtype([('a', '<f4'), ('b', '<f4'), ('c', '<f4'), ('d', '<i4')])
In[]: dt
Out[]: 'a'
In[]: data[dt].shape
Out[]: (2000, 8)
Following the suggestion in the warning message, copying the array works:
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
What would be a more elegant way to get rid of the warning? And what did the copy change in this case?