อินพุตและเอาต์พุตอาร์เรย์ numpy ไปยัง h5py


101

ฉันมีรหัส Python ที่เอาต์พุตเป็นป้อนคำอธิบายภาพที่นี่เมทริกซ์ขนาดซึ่งรายการเป็นประเภทfloatทั้งหมด ถ้าฉันบันทึกด้วยนามสกุล.datไฟล์จะมีขนาด 500 MB ฉันอ่านพบว่าการใช้h5pyลดขนาดไฟล์ลงอย่างมาก ดังนั้นขอบอกว่าผมมีอาร์เรย์ numpy 2D Aชื่อ ฉันจะบันทึกเป็นไฟล์ h5py ได้อย่างไร นอกจากนี้ฉันจะอ่านไฟล์เดียวกันและวางเป็นอาร์เรย์จำนวนนับในรหัสอื่นได้อย่างไรเนื่องจากฉันต้องจัดการกับอาร์เรย์


4
คุณประหยัดด้วย.datส่วนขยายได้อย่างไร?
jorgeca

@jorgeca: สำหรับสิ่งนั้นฉันก็ทำnp.savetxt("output.dat",A,'%10.8e')
lovespeed

3
ขอบคุณ (ส่วนขยายเพียงอย่างเดียวไม่ได้มีความหมายมากนักสามารถจัดเก็บเป็นไบนารี ascii ... ) ถ้าคุณไม่ต้องการคุณสมบัติพิเศษของ hdf5 ฉันแค่ใช้np.save('output.dat', A)ซึ่งจะบันทึกในรูปแบบไบนารี (เร็วกว่ามากใช้พื้นที่น้อยลงมาก)
jorgeca

@jorgeca แต่สคริปต์ python อื่นจะสามารถอ่านเป็นอาร์เรย์ 2 มิติได้หรือไม่เมื่อฉันเรียกมันว่าA = np.loadtxt('output.dat',unpack=True)
lovespeed

2
จึงh5pyไม่สร้างไฟล์ที่มีขนาดเล็กกว่าที่np.saveต้องการ? เป็นh5pyเร็วกว่าnp.saveสำหรับอาร์เรย์ของขนาดที่กำหนดในคำถาม?
dbliss

คำตอบ:


134

h5py ให้รูปแบบของชุดข้อมูลและกลุ่ม ก่อนหน้านี้เป็นอาร์เรย์โดยทั่วไปและหลังคุณสามารถคิดว่าเป็นไดเร็กทอรี แต่ละชื่อ คุณควรดูเอกสารประกอบสำหรับ API และตัวอย่าง:

http://docs.h5py.org/en/latest/quick.html

ตัวอย่างง่ายๆที่คุณสร้างข้อมูลทั้งหมดล่วงหน้าและต้องการบันทึกลงในไฟล์ hdf5 จะมีลักษณะดังนี้:

In [1]: import numpy as np
In [2]: import h5py
In [3]: a = np.random.random(size=(100,20))
In [4]: h5f = h5py.File('data.h5', 'w')
In [5]: h5f.create_dataset('dataset_1', data=a)
Out[5]: <HDF5 dataset "dataset_1": shape (100, 20), type "<f8">

In [6]: h5f.close()

จากนั้นคุณสามารถโหลดข้อมูลนั้นกลับมาได้โดยใช้: '

In [10]: h5f = h5py.File('data.h5','r')
In [11]: b = h5f['dataset_1'][:]
In [12]: h5f.close()

In [13]: np.allclose(a,b)
Out[13]: True

ตรวจสอบเอกสารอย่างแน่นอน:

http://docs.h5py.org

การเขียนลงไฟล์ hdf5 ขึ้นอยู่กับ h5py หรือ pytables (แต่ละตัวมี python API ที่แตกต่างกันซึ่งอยู่ด้านบนของข้อกำหนดไฟล์ hdf5) นอกจากนี้คุณควรจะดูที่รูปแบบไบนารีอื่น ๆ ที่เรียบง่ายให้โดย numpy กำเนิดเช่นnp.save, np.savezฯลฯ :

http://docs.scipy.org/doc/numpy/reference/routines.io.html


Btw. ถ้าคุณไม่ทราบชื่อของชุดข้อมูลก่อนในขณะที่อ่านคุณต้องแยกไฟล์ HDF คล้ายกับที่นี่
Trilarion

@JoshAdel ถ้าฉันต้องการเพิ่มคอลัมน์ในชุดข้อมูล ชุดข้อมูลของฉันคือ np.array หลายมิติที่จัดทำดัชนีเป็น [img_id, row, colums, channels] และฉันได้บันทึกโดยใช้วิธีการที่อธิบายไว้ในคำตอบของคุณ ฉันเข้าถึงทุกจุดในชุดข้อมูลโดยใช้ h5f ['dataset_1'] [img_id] สิ่งที่ฉันต้องการคือวิธีเพิ่มคอลัมน์อื่นพูดว่า 'mycolumn' ... ซึ่งสอดคล้องกับทุก img_id ในชุดข้อมูล ฉันจะเพิ่มคอลัมน์อื่นในคอลัมน์นี้ได้อย่างไรจึงจะสามารถทำ h5f ['mycolumn'] [img_id] ได้
iratzhash

ถ้าฉันเขียนเมทริกซ์แบบนี้ฉันจะไม่เห็นด้วย HDFView 2.11 - ฉันสามารถเปิดไฟล์ได้ฉันเห็นว่ามีชุดข้อมูลdata.h5อยู่ แต่ฉันไม่สามารถดูด้วย HDFView ได้ ฉันสามารถอ่านเนื้อหาด้วย h5py แต่ไม่สามารถตรวจสอบด้วย HDFView ได้ คิดว่าทำไม?
Martin Thoma

106

วิธีที่สะอาดกว่าในการจัดการการเปิด / ปิดไฟล์และหลีกเลี่ยงการรั่วไหลของหน่วยความจำ:

เตรียม:

import numpy as np
import h5py

data_to_write = np.random.random(size=(100,20)) # or some such

เขียน:

with h5py.File('name-of-file.h5', 'w') as hf:
    hf.create_dataset("name-of-dataset",  data=data_to_write)

อ่าน:

with h5py.File('name-of-file.h5', 'r') as hf:
    data = hf['name-of-dataset'][:]

2
ไม่จำเป็นต้องปิดไฟล์?
ricoamor

23
@DrDeSancho no, the with statement
Leonid

1
มีประโยชน์อย่างยิ่งเมื่อทำงานในโหมดโต้ตอบ (เพราะมิฉะนั้นอาจมีความเสี่ยงที่จะได้รับข้อยกเว้นจาก h5py เกี่ยวกับไฟล์ที่เปิดอยู่แล้วเมื่อรันโค้ดเดิมซ้ำโดยไม่ได้ปิดอย่างถูกต้องในครั้งแรก)
Andre Holzner

withคุณลักษณะของงูใหญ่เป็นที่รู้จักกันในฐานะผู้จัดการบริบท จะตรวจสอบให้แน่ใจว่าไฟล์ถูกปิดหลังจากใช้งานแล้ว ข้อมูลเพิ่มเติมมีอยู่ในเอกสารอย่างเป็นทางการ: docs.python.org/3/library/contextlib.html
มาระโก
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.