Извлечение и преобразование массива HDF5 в NumPy

У меня есть необработанные ежедневные данные о морских ветрах в формате HDF5, и я хочу знать, как преобразовать их в скорость и направление ветра с помощью Numpy?

Необработанные ежедневные данные о морских ветрах хранятся в двух файлах HDF5: u.hdf5 и v.hdf5. Каждый файл HDF5 содержит три элемента: широта, долгота, u(или v). Массив u(или v) является трехмерным, а 0-измерение представляет часы (0:00-24:00). Что мне нужно сделать, так это разделить массив u и v на почасовые (т.е. 0:00-1:00), а затем преобразовать их в скорость и направление ветра, используя следующий код:

#!/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)

После этого мне нужно создать еще один файл HDF5, который содержит информацию о широте, долготе, почасовой скорости и направлении ветра (s, d).

Большое спасибо!


Я пробовал с кодом ниже, но это не сработало:

>>> 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

person l.z.lz    schedule 02.05.2012    source источник
comment
да, я имел в виду радианы и спасибо за это. Я очень новичок в программировании, поэтому, если бы кто-то мог опубликовать код, это было бы здорово. Но любое предложение или подсказки будут полезны и для меня.   -  person l.z.lz    schedule 02.05.2012
comment
Я запутался, ввод uv2sd должен быть (u, v). Но я снова получил ту же ошибку, говоря, что только массивы длины 1 могут быть преобразованы в скаляры python.   -  person l.z.lz    schedule 02.05.2012
comment
вам следует попробовать numpy.sqrt и numpy.arctan2. Они могут работать с массивом u и v, а не только со скалярными u и v, которые math.sqrt ожидает   -  person yosukesabai    schedule 03.05.2012


Ответы (2)


Вы хотите, чтобы ваш скрипт возвращал вам квадратный корень массива или списка, но это невозможно, если у вас нет массива или списка из одного элемента!

Например:

import numpy as np
import math

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

Это не сработает. Вы получите ту же ошибку:

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

Вы должны вызвать функцию math.sqrt для каждого элемента массива... Например, так:

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

Теперь вы получите то, что хотите:

1.41421356237
2.0
2.44948974278

Ваш код должен работать, если вы внесете небольшие изменения в свою функцию 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
person carla    schedule 02.05.2012

Модуль struct используется для управления упакованными двоичными данными.

Вы читаете и записываете массивы символов (то есть строки) во внешний файл и внутренне конвертируете их в типы хранения Python.

Все, что вам нужно сделать, это создать функцию или класс на основе структуры, которая понимает 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
person Jason M    schedule 02.05.2012