Learn about basic functionality of dense arrays within TileDB, from ingestion to querying and beyond.
How to run this tutorial
You can run this tutorial in two ways:
Locally on your machine.
On TileDB Cloud.
However, since TileDB Cloud has a free tier, we strongly recommend that you sign up and run everything there, as that requires no installations or deployment.
This tutorial explains the most basic functionality of dense arrays, by creating a small 2×2 dense array and reading it.
First, import the necessary libraries, set the array URI (that is, its path, which in this tutorial will be on local storage), and delete any previously created arrays with the same name.
# Create the two dimensionsd1 = tiledb.Dim(name="d1", domain=(1, 4), tile=2, dtype=np.int32)d2 = tiledb.Dim(name="d2", domain=(1, 4), tile=2, dtype=np.int32)# Create a domain using the two dimensionsdom = tiledb.Domain(d1, d2)# Order of the dimensions matters when slicing subarrays.# Remember to give priority to more selective dimensions to# maximize the pruning power during slicing.# Create an attributea = tiledb.Attr(name="a", dtype=np.int32)# Create the array schema, setting `sparse=False` to indicate a dense array.# Set `cell_order` to 'row-major' (default) or 'C', 'col-major' or 'F'.# Set `tile_order` to 'row-major' (default) or 'C', 'col-major' or 'F'.sch = tiledb.ArraySchema(domain=dom, sparse=False, attrs=[a])# Create the array on disk (it will initially be empty)tiledb.Array.create(array_uri, sch)
# Create the two dimensionsd1 <-tiledb_dim("d1", c(1L, 4L), 2L, "INT32")d2 <-tiledb_dim("d2", c(1L, 4L), 2L, "INT32")# Create a domain using the two dimensionsdom <-tiledb_domain(dims =c(d1, d2))# Create an attributea <-tiledb_attr("a", type ="INT32")# Create the array schema, setting `sparse = FALSE` to indicate a dense arraysch <-tiledb_array_schema(dom, a, sparse =FALSE)# Create the array on disk (it will initially be empty)arr <-tiledb_array_create(dense_array, sch)
Note that you can specify tiling for each dimension, whereas you can set the cell and tile orders in the array schema. Tiling and the tile / cell order collectively define the data layout on storage, which plays an important role in performance. For more information, visit the following sections:
# Prepare some data in a NumPy arraydata = np.array( [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]], dtype=np.int32)# Write data to the arraywith tiledb.open(array_uri, "w") as A: A[:] = data
# Prepare some data in an arraydata <-t(array(1:16, dim =c(4, 4)))# Open the array for writing and write data to the arrayarr <-tiledb_array(uri = dense_array,query_type ="WRITE",return_as ="data.frame")arr[] <- data# Close the arrayarr <-tiledb_array_close(arr)
The array is a folder in the path specified in array_uri. You can learn about the different contents of the array folder in other sections of the Academy.
# Open the array in read modeA = tiledb.open(array_uri, "r")# Return the non-empty domain of the arrayprint("Non-empty domain: ")print(A.nonempty_domain())print("\n")# Show the entire arrayprint("Entire array: ")print(A[:])print("\n")# Show the 'a' attribute of the arrayprint("Attribute 'a': ")print(A[:]["a"])print("\n")# Slice a portion of the array, which is useful# when the arrays are too big to fit in main memoryprint("Slice [1:3), [1:2): ")print(A[1:3, 1:2]["a"])print("\n")# Slice a multi-range subarray.# Note that `multi_index` uses closed ranges.print("Multi-range, rows 1,2 and 4, and columns 1-3: ")print(A.multi_index[[slice(1, 2), 4], slice(1, 3)]["a"])# Remember to close the arrayA.close()
# Open the array in read modeinvisible(tiledb_array_open(arr, type ="READ"))# Show the entire arraycat("Entire array:\n")print(arr[])# Show the 'a' attribute of the arraycat("Attribute 'a':\n")print(arr[]["a"])# Slice a portion of the array, which is useful# when the arrays are too big to fit in main memorycat("Slice [1:2], [2:4]:\n")print(arr[1:2, 2:4]["a"])# Close the arrayinvisible(tiledb_array_close(arr))