I have some pretty simple Python code where I'm trying to label wind directions as "N", "NE", etc based on the actual direction in degrees. I am getting some really strange results, and don't know why.
dir = np.array([307,45,198,355])
Sixteen_UD = np.empty(len(dir),dtype='str')
Sixteen_UD[np.where(np.logical_or(dir >= 348.75, dir < 11.25))] = "N"
Sixteen_UD[np.where(np.logical_and(dir >= 11.25, dir < 33.75))] = 'NNE'
Sixteen_UD[np.where(np.logical_and(dir >= 33.75, dir < 56.25))] = 'NE'
Sixteen_UD[np.where(np.logical_and(dir >= 56.25, dir < 78.75))] = 'ENE'
Sixteen_UD[np.where(np.logical_and(dir >= 78.75, dir < 101.25))] = 'E'
Sixteen_UD[np.where(np.logical_and(dir >= 101.25, dir < 123.75))] = 'ESE'
Sixteen_UD[np.where(np.logical_and(dir >= 123.75, dir < 146.25))] = 'SE'
Sixteen_UD[np.where(np.logical_and(dir >= 146.25, dir < 168.75))] = 'SSE'
Sixteen_UD[np.where(np.logical_and(dir >= 168.75, dir < 191.25))] = 'S'
Sixteen_UD[np.where(np.logical_and(dir >= 191.25, dir < 213.75))] = 'SSW'
Sixteen_UD[np.where(np.logical_and(dir >= 213.75, dir < 236.25))] = 'SW'
Sixteen_UD[np.where(np.logical_and(dir >= 236.25, dir < 258.75))] = 'WSW'
Sixteen_UD[np.where(np.logical_and(dir >= 258.75, dir < 281.25))] = 'W'
Sixteen_UD[np.where(np.logical_and(dir >= 281.25, dir < 303.75))] = 'WNW'
Sixteen_UD[np.where(np.logical_and(dir >= 303.75, dir < 326.25))] = "NW"
Sixteen_UD[np.where(np.logical_and(dir >= 326.25, dir < 348.75))] = 'NNW'
This is the output I'm getting:
array(['N', 'N', 'S', 'N'], dtype='<U1')
It should be:
['NW','NE','SSW','N']
What is wrong with what I'm doing?
CodePudding user response:
Your array stores single characters:
>>> Sixteen_UD.dtype
dtype('<U1')
U
is the np.str_
unicode string type, length 1. The output is entirely correct, it's the first letter of the correct directions.
To store arbitrary-length strings, use object
as the dtype:
Sixteen_UD = np.empty(len(dir), dtype=object)
That'll store any Python object.
You could also state you want to store strings of length 3, explicitly specify a length with the U[length]
notation. Use np.zeros()
to fill this array with empty strings:
Sixteen_UD = np.zeros(len(dir), dtype='U3')
as np.empty()
can lead to somewhat random looking initial data if the array is created in an area of memory with non-zero data present.
With dtype='U3'
, the output of your code then becomes:
array(['NW', 'NE', 'SSW', 'N'], dtype='<U3')