numcube


Namenumcube JSON
Version 0.2.1 PyPI version JSON
download
home_pagehttp://github.com/vladimir-kraus/numcube
SummaryNumcube extends the functionality of numpy multidimensional arrays by adding named and annotated axes.
upload_time2022-12-30 17:52:49
maintainer
docs_urlNone
authorVladimir Kraus
requires_python
licenseMIT
keywords cube multidimensional array axis
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            numcube package
===============

Numcube extends the functionality of numpy multidimensional arrays by adding named and annotated axes. Such
structures are called cubes. Numcube allows operations involving multiple cubes with automatic axis matching and
alignment. It allows filtering and aggregations based on the axis values. One of the goals was to provide API similar
to numpy. Internally it uses numpy arrays for the underlying array and axes as well.

Axis matching
-------------

In operations involving multiple cubes, the axes are matched and aligned. Matching means that axis names are compared
and the axes with the same names are aligned (see below), while the unique axes are broadcast (see array
broadcasting).

The cube is meant to not depend on the specific order of axes in most of the features. Nevertheless, the output of
the operation has the same order of axes as the first cube in the operation, followed by unique axes from the other
cubes respecting their order.

Axis alignment
--------------

There are basically two types of axes. There are two types of axes - Index and Series. Series has a fixed order or
values and the values do not need to be unique. Index must have unique values, which can be used for look up during
axis alignment.

If one of the axes is Series and the other is Index, then the values in Series must be subset of those in Index; the
result axis is the Series axis.

If both axes are of type Index, they must contain the same values; the values however can have different order; the
result axis is the first Index axis.

If both axes are Series, they must be equivalent - they must contain the same values in the same order. The result
axis is the first Series axis.

Filtering values
----------------

Cubes can be filtered using three distinct methods: 
1) filtering by axis values - function filter(...)
2) filtering by index along axes - function take(...)
3) filtering by logical selectors along axes - function compress(...)

Functions take(...) and compress(...) have the same semantics as in numpy package.

```python
>> from numcube import Index, Cube
>> Y = Index("year", range(2014, 3))
>> Q = Index("quarter", ["Q1", "Q2", "Q3", "Q4"])
>> sales = Cube([[14, 16, 13, 20], [15, 15, 10, 19], [16, 17, 15, 21]], [Y, Q])
>> # filter by dimension attribute
>> salesH1 = sales.filter("quarter", ["Q1", "Q2"])  
>> # filter by numeric indices
>> salesH1 = sales.take("quarter", [0, 1]) 
>> # filter by logical vector
>> filter_q = np.array([True, True, False, False]
>> salesH1 = sales.compress("quarter", filter_q))  
```

Operators
---------

Cubes support arithmetical operations between two cubes. The cube axes are matched and aligned and the operations 
are performed element-wise.

```python
>> from numcube import Index, Cube
>> year_ax = Index("year", [2014, 2015])
>> quarter_ax = Index("quarter", ["Q1", "Q2", "Q3", "Q4"])
>> sales = Cube([[14, 16, 13, 20], [15, 15, 10, 19]], [year_ax, quarter_ax])
>> prices = Cube([1.50, 1.52, 1.53, 1.55], [year_ax])
>> revenues_q = sales * prices  # quarterly revenues
```

Cube can also be in operation with a scalar value, which is treated as dimensionless Cube. 

```python
>> Y = Index("year", range(2014, 2))
>> Q = Index("quarter", ["Q1", "Q2", "Q3", "Q4"])
>> prices = Cube([[1.50, 1.52, 1.53, 1.55], [1.48, 1.47, 1.46, 1.49], [Y, Q])
>> discount = 0.5
>> discounted_prices = sales * discount  # operation with scalar
```

Aggregations
------------

Cube values can be aggregated along axes using aggregation functions sum, mean, min, max, etc. All aggregation
functions allow defining which axes are going to be aggregated, which are to be kept or values on which are going
to be grouped.

```python
>> total_revenues = revenues.sum()
>> average_annual_revenues = revenues.mean("quarter")
>> total_annual_revenues = revenues.sum(keep="year")
```

Aggregations can be also used to group values along an axis with non-unique values., for example:
```python
>> subject = Axis('subject', [math', 'biology', 'math', 'physics', 'math', 'biology', 'math', 'physics'])
>> score = Cube([65, 80, 95, 52, 35, 50, 89, 95], subject)
>> score_by_subject = score.mean(group='subject')
```

General aggregation function is reduce(), which it is possible to provide with a user defined aggregation function.
```python
>> decile_9th = score.reduce(func=lambda x: np.percentile(x, 90.0))
```

Logical aggregation functions all() and any() can be used to test whether all or any logical value in a cube is True.
```python
>> c = Cube(...)
>> d = Cube(...)
>> if (c > d).all():  # to test if all values in c are greater than respective values in d
```
Note that comparison operators use the same axis matching, alignment adn broadcasting as normal arithmetic operators.

Other
-----

- the interface of all classes is designed to support immutability
- Cube supports numerical functions such as sin, cos, log, exp etc.
- transposition (in n-dimensional space) changes the order of axes


            

Raw data

            {
    "_id": null,
    "home_page": "http://github.com/vladimir-kraus/numcube",
    "name": "numcube",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "cube,multidimensional,array,axis",
    "author": "Vladimir Kraus",
    "author_email": "vladimir.kraus@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/75/b9/9b230b0ffef3d93b1289012571d59d3c4dd54c09da412151b80b73ca8af7/numcube-0.2.1.tar.gz",
    "platform": null,
    "description": "numcube package\n===============\n\nNumcube extends the functionality of numpy multidimensional arrays by adding named and annotated axes. Such\nstructures are called cubes. Numcube allows operations involving multiple cubes with automatic axis matching and\nalignment. It allows filtering and aggregations based on the axis values. One of the goals was to provide API similar\nto numpy. Internally it uses numpy arrays for the underlying array and axes as well.\n\nAxis matching\n-------------\n\nIn operations involving multiple cubes, the axes are matched and aligned. Matching means that axis names are compared\nand the axes with the same names are aligned (see below), while the unique axes are broadcast (see array\nbroadcasting).\n\nThe cube is meant to not depend on the specific order of axes in most of the features. Nevertheless, the output of\nthe operation has the same order of axes as the first cube in the operation, followed by unique axes from the other\ncubes respecting their order.\n\nAxis alignment\n--------------\n\nThere are basically two types of axes. There are two types of axes - Index and Series. Series has a fixed order or\nvalues and the values do not need to be unique. Index must have unique values, which can be used for look up during\naxis alignment.\n\nIf one of the axes is Series and the other is Index, then the values in Series must be subset of those in Index; the\nresult axis is the Series axis.\n\nIf both axes are of type Index, they must contain the same values; the values however can have different order; the\nresult axis is the first Index axis.\n\nIf both axes are Series, they must be equivalent - they must contain the same values in the same order. The result\naxis is the first Series axis.\n\nFiltering values\n----------------\n\nCubes can be filtered using three distinct methods: \n1) filtering by axis values - function filter(...)\n2) filtering by index along axes - function take(...)\n3) filtering by logical selectors along axes - function compress(...)\n\nFunctions take(...) and compress(...) have the same semantics as in numpy package.\n\n```python\n>> from numcube import Index, Cube\n>> Y = Index(\"year\", range(2014, 3))\n>> Q = Index(\"quarter\", [\"Q1\", \"Q2\", \"Q3\", \"Q4\"])\n>> sales = Cube([[14, 16, 13, 20], [15, 15, 10, 19], [16, 17, 15, 21]], [Y, Q])\n>> # filter by dimension attribute\n>> salesH1 = sales.filter(\"quarter\", [\"Q1\", \"Q2\"])  \n>> # filter by numeric indices\n>> salesH1 = sales.take(\"quarter\", [0, 1]) \n>> # filter by logical vector\n>> filter_q = np.array([True, True, False, False]\n>> salesH1 = sales.compress(\"quarter\", filter_q))  \n```\n\nOperators\n---------\n\nCubes support arithmetical operations between two cubes. The cube axes are matched and aligned and the operations \nare performed element-wise.\n\n```python\n>> from numcube import Index, Cube\n>> year_ax = Index(\"year\", [2014, 2015])\n>> quarter_ax = Index(\"quarter\", [\"Q1\", \"Q2\", \"Q3\", \"Q4\"])\n>> sales = Cube([[14, 16, 13, 20], [15, 15, 10, 19]], [year_ax, quarter_ax])\n>> prices = Cube([1.50, 1.52, 1.53, 1.55], [year_ax])\n>> revenues_q = sales * prices  # quarterly revenues\n```\n\nCube can also be in operation with a scalar value, which is treated as dimensionless Cube. \n\n```python\n>> Y = Index(\"year\", range(2014, 2))\n>> Q = Index(\"quarter\", [\"Q1\", \"Q2\", \"Q3\", \"Q4\"])\n>> prices = Cube([[1.50, 1.52, 1.53, 1.55], [1.48, 1.47, 1.46, 1.49], [Y, Q])\n>> discount = 0.5\n>> discounted_prices = sales * discount  # operation with scalar\n```\n\nAggregations\n------------\n\nCube values can be aggregated along axes using aggregation functions sum, mean, min, max, etc. All aggregation\nfunctions allow defining which axes are going to be aggregated, which are to be kept or values on which are going\nto be grouped.\n\n```python\n>> total_revenues = revenues.sum()\n>> average_annual_revenues = revenues.mean(\"quarter\")\n>> total_annual_revenues = revenues.sum(keep=\"year\")\n```\n\nAggregations can be also used to group values along an axis with non-unique values., for example:\n```python\n>> subject = Axis('subject', [math', 'biology', 'math', 'physics', 'math', 'biology', 'math', 'physics'])\n>> score = Cube([65, 80, 95, 52, 35, 50, 89, 95], subject)\n>> score_by_subject = score.mean(group='subject')\n```\n\nGeneral aggregation function is reduce(), which it is possible to provide with a user defined aggregation function.\n```python\n>> decile_9th = score.reduce(func=lambda x: np.percentile(x, 90.0))\n```\n\nLogical aggregation functions all() and any() can be used to test whether all or any logical value in a cube is True.\n```python\n>> c = Cube(...)\n>> d = Cube(...)\n>> if (c > d).all():  # to test if all values in c are greater than respective values in d\n```\nNote that comparison operators use the same axis matching, alignment adn broadcasting as normal arithmetic operators.\n\nOther\n-----\n\n- the interface of all classes is designed to support immutability\n- Cube supports numerical functions such as sin, cos, log, exp etc.\n- transposition (in n-dimensional space) changes the order of axes\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Numcube extends the functionality of numpy multidimensional arrays by adding named and annotated axes.",
    "version": "0.2.1",
    "split_keywords": [
        "cube",
        "multidimensional",
        "array",
        "axis"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "md5": "2d4d158de37e80d1d6e7e04248a26a3e",
                "sha256": "7c02a4ba4837b77801e9ec282bd9e0ed37872bff459bac6b8c4c55fb6fd9acb8"
            },
            "downloads": -1,
            "filename": "numcube-0.2.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "2d4d158de37e80d1d6e7e04248a26a3e",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 36346,
            "upload_time": "2022-12-30T17:52:47",
            "upload_time_iso_8601": "2022-12-30T17:52:47.590065Z",
            "url": "https://files.pythonhosted.org/packages/8c/79/4a5fa032e87eefe9d2977923bb519d2fb65bef19e9243e7c3e4ddb83ed94/numcube-0.2.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "md5": "4baebcdd96d9b5cdabbdb152fdc1cbda",
                "sha256": "226a4d845739f76b58d12e176efa56b51b6d75bc5eb6e37766d06df645972ecf"
            },
            "downloads": -1,
            "filename": "numcube-0.2.1.tar.gz",
            "has_sig": false,
            "md5_digest": "4baebcdd96d9b5cdabbdb152fdc1cbda",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 33214,
            "upload_time": "2022-12-30T17:52:49",
            "upload_time_iso_8601": "2022-12-30T17:52:49.286982Z",
            "url": "https://files.pythonhosted.org/packages/75/b9/9b230b0ffef3d93b1289012571d59d3c4dd54c09da412151b80b73ca8af7/numcube-0.2.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2022-12-30 17:52:49",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "vladimir-kraus",
    "github_project": "numcube",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "numcube"
}
        
Elapsed time: 0.02225s