Repository: TileDB-Inc/TileDB-Py

Issue:
Junk results using numpy structured arrays
Hey, 

I am attempting to use a sparse multi attribute arrays but for some reason I seem to be getting junk results

TileDB-Py version (0.33.4)
Python version (3.6.9)

Here is a reproducing example (apologies that it is not very minimal)
```
import numpy as np
from numpy import array
import tiledb
import shutil
from contextlib import suppress

# define a domain and schema
NOTES_DTYPE = [('swing', 'float32', 1), ('pitch', 'uint8', 1), ('duration', 'float32', 1), ('velocity', 'uint8', 1)]


song_dim = tiledb.Dim(name="song_idx", domain=(0, np.iinfo(np.int32).max-1), tile=1, dtype=np.int32)
track_dim = tiledb.Dim(name="track_idx", domain=(0, np.iinfo(np.int32).max-1), tile=1, dtype=np.int32)
bar_dim = tiledb.Dim(name="bar_idx", domain=(0, np.iinfo(np.int32).max-1), tile=1, dtype=np.int32)
beat_dim = tiledb.Dim(name="beat_no", domain=(0, 3), tile=1, dtype=np.int32)
note_dim = tiledb.Dim(name="note_idx", domain=(0, np.iinfo(np.int32).max-1), tile=1, dtype=np.int32)

notes_dom = tiledb.Domain(
    song_dim,
    track_dim,
    bar_dim,
    beat_dim,
    note_dim,
)

notes_schema = tiledb.ArraySchema(domain=notes_dom, sparse=True,
    attrs=[
        tiledb.Attr(name=prop_name, dtype=getattr(np, dtype))
                for prop_name, dtype, _ in NOTES_DTYPE]
)

# define some test data
test_data = {'notes_coords': array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[0, 0, 0, 1, 1, 1, 2, 2, 2, 2],[0, 1, 2, 0, 1, 2, 0, 1, 2, 3]]), 
    'notes_data': array([( 0.  , 78, 0.25, 127), ( 0.25, 66, 0.25, 127),( 0.5 , 82, 0.25, 127), (-0.25, 66, 0.25, 127),( 0.  , 80, 0.25, 127), ( 0.25, 66, 0.25, 127),(-0.5 , 72, 0.25, 127), (-0.25, 66, 0.25, 127),( 0.  , 73, 0.25, 127), ( 0.25, 66, 0.25, 127)], dtype=[('swing', '<f4'), ('pitch', 'u1'), ('duration', '<f4'), ('velocity', 'u1')])
}

# create array
with suppress(FileNotFoundError):
    shutil.rmtree(f'test_tile')
tiledb.SparseArray.create(f'test_tile', notes_schema)


# write test data to array
tile_array = lambda mode: tiledb.SparseArray('test_tile', mode=mode)

stuctured_array_to_dict = lambda arr: {name: arr[name] for name in arr.dtype.names}

with tile_array('w') as A:
    A[(*test_data['notes_coords'],)] = \
        stuctured_array_to_dict(test_data['notes_data'])


# read data back from array
with tile_array('r') as A:
    from_tile = A[0]


# none are matching
assert any([(from_tile['velocity']==test_data['notes_data']['velocity']).all(),
(from_tile['swing']==test_data['notes_data']['swing']).all(),
(from_tile['pitch']==test_data['notes_data']['pitch']).all(),
(from_tile['duration']==test_data['notes_data']['duration']).all()])
```

upon inspecting these array it can be seen that the data in them looks to be uninitialized (floats are >1e40)

Am I perhaps missing something important here?


Discussion:
I have found that if I make the following change
before  `stuctured_array_to_dict = lambda arr: {name: arr[name] for name in arr.dtype.names}`
after `stuctured_array_to_dict = lambda arr: {name: np.array(arr[name]) for name in arr.dtype.names}`

then things work as expected

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -564,6 +564,7 @@ def ext_attr_update(attr, value):
     tests_require=TESTS_REQUIRE,
     packages=find_packages(),
     cmdclass=LazyCommandClass(),
+    zip_safe=False,
     classifiers=[
         'Development Status :: 4 - Beta',
         'Intended Audience :: Developers',


Test patch: