Skip to main content

Manipulate arrays of complex data structures as easily as Numpy.

Project description

awkward-array is a pure Python+Numpy library for manipulating complex data structures as you would Numpy arrays. Even if your data structures

  • contain variable-length lists (jagged or ragged),

  • are deeply nested (record structure),

  • have different data types in the same list (heterogeneous),

  • are masked, bit-masked, or index-mapped (nullable),

  • contain cross-references or even cyclic references,

  • need to be Python class instances on demand,

  • are not defined at every point (sparse),

  • are not contiguous in memory,

  • should not be loaded into memory all at once (lazy),

this library can access them with the efficiency of Numpy arrays. They may be converted from JSON or Python data, loaded from “awkd” files, HDF5, Parquet, or ROOT files, or they may be views into memory buffers like Arrow.

Consider this monstrosity:

import awkward
array = awkward.fromiter([[1.1, 2.2, None, 3.3, None],
                          [4.4, [5.5]],
                          [{"x": 6, "y": {"z": 7}}, None, {"x": 8, "y": {"z": 9}}]
                         ])

It’s a list of lists; the first contains numbers and None, the second contains a sub-sub-list, and the third defines nested records. If we print this out, we see that it is called a JaggedArray:

array
# returns <JaggedArray [[1.1 2.2 None 3.3 None] [4.4 [5.5]] [<Row 0> None <Row 1>]] at 79093e598f98>

and we get the full Python structure back by calling array.tolist():

array.tolist()
# returns [[1.1, 2.2, None, 3.3, None],
#          [4.4, [5.5]],
#          [{'x': 6, 'y': {'z': 7}}, None, {'x': 8, 'y': {'z': 9}}]]

But we can also manipulate it as though it were a Numpy array. We can, for instance, take the first two elements of each sub-list (slicing the second dimension):

array[:, :2]
# returns <JaggedArray [[1.1 2.2] [4.4 [5.5]] [<Row 0> None]] at 79093e5ab080>

or the last two:

array[:, -2:]
# returns <JaggedArray [[3.3 None] [4.4 [5.5]] [None <Row 1>]] at 79093e5ab3c8>

Internally, the data has been rearranged into a columnar form, with all values at a given level of hierarchy in the same array. Numpy-like slicing, masking, and fancy indexing are translated into Numpy operations on these internal arrays: they are not implemented with Python for loops!

To see some of this structure, ask for the content of the array:

array.content
# returns <IndexedMaskedArray [1.1 2.2 None ... <Row 0> None <Row 1>] at 79093e598ef0>

Notice that the boundaries between sub-lists are gone: they exist only at the JaggedArray level. This IndexedMaskedArray level handles the None values in the data. If we dig further, we’ll find a UnionArray to handle the mixture of sub-lists and sub-sub-lists and record structures. If we dig deeply enough, we’ll find the numerical data:

array.content.content.contents[0]
# returns array([1.1, 2.2, 3.3, 4.4])
array.content.content.contents[1].content
# returns array([5.5])

Perhaps most importantly, Numpy’s universal functions (operations that apply to every element in an array) can be used on our array. This, too, goes straight to the columnar data and preserves structure.

array + 100
# returns <JaggedArray [[101.1 102.2 None 103.3 None]
#                       [104.4 [105.5]]
#                       [<Row 0> None <Row 1>]] at 724509ffe2e8>

(array + 100).tolist()
# returns [[101.1, 102.2, None, 103.3, None],
#          [104.4, [105.5]],
#          [{'x': 106, 'y': {'z': 107}}, None, {'x': 108, 'y': {'z': 109}}]]

numpy.sin(array)
# returns <JaggedArray [[0.8912073600614354 0.8084964038195901 None -0.1577456941432482 None]
#                       [-0.951602073889516 [-0.70554033]]
#                       [<Row 0> None <Row 1>]] at 70a40c3a61d0>

Rather than matching the speed of compiled code, this can exceed the speed of compiled code (on non-columnar data) because the operation may be vectorized on awkward-array’s underlying columnar arrays.

(To do: performance example to substantiate that claim.)

Installation

Install awkward-array like any other Python package:

pip install awkward

or similar (use sudo, --user, virtualenv, or pip-in-conda if you wish).

Strict dependencies:

Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

awkward-0.8.0rc4.tar.gz (60.1 kB view details)

Uploaded Source

Built Distributions

awkward-0.8.0rc4-py3.7.egg (186.3 kB view details)

Uploaded Source

awkward-0.8.0rc4-py2.py3-none-any.whl (82.1 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file awkward-0.8.0rc4.tar.gz.

File metadata

  • Download URL: awkward-0.8.0rc4.tar.gz
  • Upload date:
  • Size: 60.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.5.0.1 requests/2.19.1 setuptools/40.6.3 requests-toolbelt/0.8.0 tqdm/4.29.1 CPython/3.7.0

File hashes

Hashes for awkward-0.8.0rc4.tar.gz
Algorithm Hash digest
SHA256 94fca6b49b4d22014411cbc8e9d92b8cf9602f037f9c659cf9a42ae2a2618cc9
MD5 2850f296254fa4ceb75d3ee73135b163
BLAKE2b-256 28e35110ebe1568166fe01ae0712228ec604578ce4d79a47c81ca975b599a18e

See more details on using hashes here.

File details

Details for the file awkward-0.8.0rc4-py3.7.egg.

File metadata

  • Download URL: awkward-0.8.0rc4-py3.7.egg
  • Upload date:
  • Size: 186.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.5.0.1 requests/2.19.1 setuptools/40.6.3 requests-toolbelt/0.8.0 tqdm/4.29.1 CPython/3.7.0

File hashes

Hashes for awkward-0.8.0rc4-py3.7.egg
Algorithm Hash digest
SHA256 07ff03afc5ab717281cbcfc7a5d939c7056f87e1ed7781d97d508d6f801a0c76
MD5 fbe3d58c30b25ca1f98da860ec37a7ce
BLAKE2b-256 0b5f577a01335abb83cdb0f32ee63099b93b1c1c209fe5629c8f44dd2623667a

See more details on using hashes here.

File details

Details for the file awkward-0.8.0rc4-py2.py3-none-any.whl.

File metadata

  • Download URL: awkward-0.8.0rc4-py2.py3-none-any.whl
  • Upload date:
  • Size: 82.1 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.5.0.1 requests/2.19.1 setuptools/40.6.3 requests-toolbelt/0.8.0 tqdm/4.29.1 CPython/3.7.0

File hashes

Hashes for awkward-0.8.0rc4-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 ba1971e589ef3958c7df5eab2c2aced952025bb5306d7f929f8085d16aded934
MD5 1238493cf5d2f95af57934aacdbeffe9
BLAKE2b-256 60e34a34918bbccb89eea2ebff2deb433950b71c02830c6bb5f81fe22ca765e9

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page