l.z.lz
l.z.lz

Reputation: 393

HDF5 array extraction and conversion in NumPy

I have some raw daily sea winds data in HDF5 format and want to know how to convert them into wind speed and wind direction using Numpy?

The raw daily sea winds data are stored in two HDF5 files: u.hdf5 and v.hdf5. Each HDF5 file contains three contents: latitude,longitude,u(or v).The u(or v)array is 3D, with the 0-Dimension represents hours(0:00-24:00). What I need to do is slicing the u and v array into hourly(ie 0:00-1:00), and then convert them into wind speed and wind direction using following code:

#!/usr/bin/python2

import os
import sys
import math


def d2r(degree):
  radian = degree * math.pi / 180.0
  return (radian)


def r2d(radian):
  degree = radian * 180.0 / math.pi
  return (degree)


def uv2sd(u,v):
  s = math.sqrt((u*u)+(v*v))
  radian = math.atan2(u,v)
  degree = r2d(radian)
  if degree < 0:
    degree = 360 + degree
  return (s,d)

After that I need to create another HDF5 file that contains latitude, longitude and hourly wind speed and wind direction (s,d) information.

Thanks a lot!


I tried with the code below but it didn't work:

>>> import numpy
>>> import h5py
>>> import os
>>> import sys
>>> import math

>>> a=h5py.File('D:/Wind/u_100m/20100101.hdf5','r')
>>> b=a['u'].value
>>> c=b[0,:,:]
>>> cu=c
>>> d=h5py.File('D:/Wind/v_100m/20100101.hdf5','r')
>>> e=d['v'].value
>>> f=e[0,:,:]
>>> fv=f

>>> u=cu.reshape(-1)
>>> v=fv.reshape(-1)


>>> def d2r(d):
    r=d*math.pi/180.0
    return(r)

>>> def r2d(r):
    d=r*180.0/math.pi
    return(d)

>>> def uv2sd(u,v):
    s=math.sqrt((u*u)+(v*v))
    d=math.atan2(u,v)
    if d<0:
        d=360+d
    return (s,d)

>>> print uv2sd(u,v)

Traceback (most recent call last):
  File "<pyshell#55>", line 1, in <module>
    print uv2sd(u,v)
  File "<pyshell#54>", line 2, in uv2sd
    s=math.sqrt((u*u)+(v*v))
TypeError: only length-1 arrays can be converted to Python scalars

Upvotes: 0

Views: 1863

Answers (2)

carla
carla

Reputation: 2251

You want your script to return you the square root of an array or a list, but that is not possible unless you have a one element array or list!

As an example:

import numpy as np
import math

a = np.array([2, 4, 6])
s = math.sqrt(a)

This won't work. You'll get the same error:

TypeError: only length-1 arrays can be converted to Python scalars

You have to call the math.sqrt function for each element of the array... For example like this:

for i in a:
    s = math.sqrt(i)
    print s

Now you will get what you want:

1.41421356237
2.0
2.44948974278

Your code should work if you do some small changes on your function uv2sd:

def uv2sd(u,v):
    s = []
    d = []
    for i in range(len(u)):
        angulo = math.atan2(u[i],v[i])
        if angulo < 0:
            angulo = 360 + angulo
        d.append(angulo)
        s.append(math.sqrt((u[i]*u[i])+(v[i]*v[i])))     
    return s, d

Upvotes: 1

Jay M
Jay M

Reputation: 4287

The struct module is used to manipulate binary packed data.

You read and write character arrays (i.e. strings) to an external file and internlly convert them into python storage types.

All you have to do is create a function or class based on struct that understands HDF5

e.g.

import struct
f=open("infile.dat","rb")

s=struct.Struct('fl')
BLOCKSIZE=s.size()

mydata=[]
data=f.read()
f.close()
for p in range(0,len(data),BLOCKSIZE):
    b=data[p:p+BLOCKSIZE]
    mydata.append(s.unpack(b))
print mydata

Upvotes: 0

Related Questions