Repository navigation
Read arrays with the struct data type - #464
Open
bendichter wants to merge 1 commit into
Open
bendichter wants to merge 1 commit into
bendichter wants to merge 1 commit into
Conversation
struct is the registered Zarr v3 data type for records of named fields, like a NumPy structured dtype. Its metadata is an object, and opening such an array failed with "dataType.match is not a function". A chunk of a struct array is a new StructArray, next to BoolArray and the string arrays. It is a view of the packed records, and each element reads through a DataView as an object with a value for every field. Fields can be the numeric types, bool, fixed_length_utf32, zarr-python's null_terminated_bytes, and another struct. The bytes codec reverses each field on its own for big-endian data. Arrays written under the earlier name, structured, with fields as pairs and a base64 fill value, are read as struct, as the registry asks of readers. The fixtures are written by zarr-python: the earlier form by the version generate-v3.py pins, and struct by a second script that needs a newer one. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 171cf1f The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #463.
This lets zarrita read arrays with the
structdata type, which holds records of named fields like a NumPy structured dtype.What It Adds
StructArray, next toBoolArrayand the string arrays. It is a view of the packed records, with the samebuffer,byteOffset,byteLength, andBYTES_PER_ELEMENTthat the indexing code copies bytes with, sogetand slicing needed no change. Each element reads through aDataViewas an object with a value for every field. Fields are packed with no padding, so a record can be 13 bytes and start at any offset, which a typed array could not view.bool,fixed_length_utf32, zarr-python'snull_terminated_bytes, and a nestedstruct. Any other field type raisesInvalidMetadataError.bytescodec reverses each field on its own, on a copy. AStructArrayis little-endian in memory.int64fields becomebigint,"NaN"and the infinities become numbers, and a byte string field is decoded from base64.structuredbeforestructwas registered, with fields as[name, data_type]pairs, a base64 fill value, and abytescodec withoutendian. The registry asks readers to accept that form. It is converted tostructwhen the metadata is read, soarr.dtypeis the same for both.Structjoins theDataTypeunion, withStructScalaras its scalar, andarr.is("struct")narrows to it.Any other data type that is an object in the metadata, such as
numpy.datetime64, now raisesInvalidMetadataErrorwith the type in the message. It was the sameTypeErrorbefore.What It Leaves Out
Writing is not covered.
settreats any object value as a chunk, so a struct scalar cannot be set, andcreatecannot encode a fill value that holds abigintor a byte string. I kept this to reading.Fixtures
generate-v3.pypins zarr-python withexclude-newer, and that version writesstructured. I used it for the earlier form (1d.chunked.structured) and addedgenerate-v3-struct.py, which needs zarr-python 3.4, for1d.chunked.struct,1d.chunked.struct.be, and2d.chunked.compressed.struct. All four have chunks that were never written, to cover the fill value.I added only these four arrays. Running
update-fixturesrewrites the compressed bytes of every existing fixture, so I left those and the zip archives as they are.Testing
Unit tests cover
StructArrayand thebytescodec with little- and big-endian records. The fixture tests read the same records in all three forms and compare them with what zarr-python wrote. I also read a compound column from an NWB file written by hdmf-zarr by hand (int32,int32, and a 2048-bytefixed_length_utf32, zstd-compressed), and got the values zarr-python reads.Would you prefer the second fixture script, or moving the pin in
generate-v3.pyforward and regenerating everything?🤖 Generated with Claude Code