numpack


Namenumpack JSON
Version 0.2.1 PyPI version JSON
download
home_pageNone
SummaryA high-performance array storage and manipulation library
upload_time2025-07-22 16:35:27
maintainerNone
docs_urlNone
authorNumPack Contributors
requires_python>=3.9
licenseNone
keywords numpy array storage performance
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # NumPack

NumPack is a lightning-fast array manipulation engine that revolutionizes how you handle large-scale NumPy arrays. By combining Rust's raw performance with Python's ease of use, NumPack delivers up to 20x faster operations than traditional methods, while using minimal memory. Whether you're working with gigabyte-sized matrices or performing millions of array operations, NumPack makes it effortless with its zero-copy architecture and intelligent memory management.

Key highlights:
- 🚀 Up to 20x faster than traditional NumPy storage methods
- 💾 Zero-copy operations for minimal memory footprint
- 🔄 Seamless integration with existing NumPy workflows
- 🛠 Battle-tested in production with arrays exceeding 1 billion rows

## Features

- **High Performance**: Optimized for both reading and writing large numerical arrays
- **Lazy Loading Support**: Efficient memory usage through on-demand data loading
- **Selective Loading**: Load only the arrays you need, when you need them
- **In-place Operations**: Support for in-place array modifications without full file rewrite
- **Parallel I/O**: Utilizes parallel processing for improved performance
- **Multiple Data Types**: Supports various numerical data types including:
  - Boolean
  - Unsigned integers (8-bit to 64-bit)
  - Signed integers (8-bit to 64-bit)
  - Floating point (32-bit and 64-bit)

## Installation

### From PyPI (Recommended)

#### Prerequisites
- Python >= 3.9
- NumPy >= 1.26.0

```bash
pip install numpack
```

### From Source

To build and install NumPack from source, you need to meet the following requirements:

#### Prerequisites

- Python >= 3.9
- Rust >= 1.70.0
- NumPy >= 1.26.0
- Appropriate C/C++ compiler (depending on your operating system)
  - Linux: GCC or Clang
  - macOS: Clang (via Xcode Command Line Tools)
  - Windows: MSVC (via Visual Studio or Build Tools)

#### Build Steps

1. Clone the repository:
```bash
git clone https://github.com/BirchKwok/NumPack.git
cd NumPack
```

2. Install maturin (for building Rust and Python hybrid projects):
```bash
pip install maturin>=1.0,<2.0
```

3. Build and install:
```bash
# Install in development mode
maturin develop

# Or build wheel package
maturin build --release
pip install target/wheels/numpack-*.whl
```

#### Platform-Specific Notes

- **Linux Users**:
  - Ensure python3-dev (Ubuntu/Debian) or python3-devel (Fedora/RHEL) is installed
  - If using conda environment, make sure the appropriate compiler toolchain is installed

- **macOS Users**:
  - Make sure Xcode Command Line Tools are installed: `xcode-select --install`
  - Supports both Intel and Apple Silicon architectures

- **Windows Users**:
  - Visual Studio or Visual Studio Build Tools required
  - Ensure "Desktop development with C++" workload is installed


## Usage

### Basic Operations

```python
import numpy as np
from numpack import NumPack

# Create a NumPack instance
npk = NumPack("data_directory")

# Save arrays
arrays = {
    'array1': np.random.rand(1000, 100).astype(np.float32),
    'array2': np.random.rand(500, 200).astype(np.float32)
}
npk.save(arrays)

# Load arrays
# Normal mode
loaded = npk.load("array1")

# lazy load
lazy_array = npk.load("arr1", lazy=True)
```

### Advanced Operations

```python
# Replace specific rows
replacement = np.random.rand(10, 100).astype(np.float32)
npk.replace({'array1': replacement}, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])  # Using list indices
npk.replace({'array1': replacement}, slice(0, 10))  # Using slice notation

# Append new arrays
new_arrays = {
    'array3': np.random.rand(200, 100).astype(np.float32)
}
npk.append(new_arrays)

# Drop arrays or specific rows
npk.drop('array1')  # Drop entire array
npk.drop(['array1', 'array2'])  # Drop multiple arrays
npk.drop('array2', [0, 1, 2])  # Drop specific rows

# Random access operations
data = npk.getitem('array1', [0, 1, 2])  # Access specific rows
data = npk.getitem('array1', slice(0, 10))  # Access using slice
data = npk['array1']  # Dictionary-style access for entire array

# Metadata operations
shapes = npk.get_shape()  # Get shapes of all arrays
shapes = npk.get_shape('array1')  # Get shape of specific array
members = npk.get_member_list()  # Get list of array names
mtime = npk.get_modify_time('array1')  # Get modification time
metadata = npk.get_metadata()  # Get complete metadata

# Stream loading for large arrays
for batch in npk.stream_load('array1', buffer_size=1000):
    # Process 1000 rows at a time
    process_batch(batch)

# Reset/clear storage
npk.reset()  # Clear all arrays

# Iterate over all arrays
for array_name in npk:
    data = npk[array_name]
    print(f"{array_name} shape: {data.shape}")
```

### Lazy Loading and Buffer Operations

NumPack supports lazy loading and buffer operations, which are particularly useful for handling large-scale datasets. Using the `lazy=True` parameter enables data to be loaded only when actually needed, making it ideal for streaming processing or scenarios where only partial data access is required.

```python
from numpack import NumPack
import numpy as np

# Create NumPack instance and save large-scale data
npk = NumPack("test_data/", drop_if_exists=True)
a = np.random.random((1000000, 128))  # Create a large array
npk.save({"arr1": a})

# Lazy loading - keeps data in buffer
lazy_array = npk.load("arr1", lazy=True)  # LazyArray Object

# Perform computations with lazy-loaded data
# Only required data is loaded into memory
similarity_scores = np.inner(a[0], npk.load("arr1", lazy=True))
```

## Performance

NumPack offers significant performance improvements compared to traditional NumPy storage methods, especially in data modification operations and random access. Below are detailed benchmark results:

### Benchmark Results

The following benchmarks were performed on an MacBook Pro (Apple Silicon) with arrays of size 1M x 10 and 500K x 5 (float32).

#### Storage Operations

| Operation | NumPack (Best) | NumPack (Python) | NumPy NPZ | NumPy NPY |
|-----------|----------------|------------------|-----------|-----------|
| Save | 0.015s (0.96x NPZ, 0.55x NPY) | 0.015s (0.96x NPZ, 0.55x NPY) | 0.014s | 0.008s |
| Full Load | 0.007s (1.89x NPZ, 1.02x NPY) | 0.009s (1.56x NPZ, 0.85x NPY) | 0.014s | 0.008s |
| Selective Load | 0.006s (1.61x NPZ, -) | 0.006s (1.61x NPZ, -) | 0.010s | - |

#### Data Modification Operations

| Operation | NumPack (Best) | NumPack (Python) | NumPy NPZ | NumPy NPY |
|-----------|----------------|------------------|-----------|-----------|
| Single Row Replace | 0.000s (≥156x NPZ, ≥90x NPY) | 0.000s (≥156x NPZ, ≥90x NPY) | 0.024s | 0.014s |
| Continuous Rows (10K) | 0.001s (24.00x NPZ, 14.00x NPY) | 0.001s (24.00x NPZ, 14.00x NPY) | 0.024s | 0.014s |
| Random Rows (10K) | 0.014s (1.71x NPZ, 1.00x NPY) | 0.014s (1.71x NPZ, 1.00x NPY) | 0.024s | 0.014s |
| Large Data Replace (500K) | 0.018s (1.33x NPZ, 0.78x NPY) | 0.020s (1.20x NPZ, 0.70x NPY) | 0.024s | 0.014s |

#### Drop Operations

| Operation (1M rows, float32) | NumPack (Best) | NumPack (Python) | NumPy NPZ | NumPy NPY |
|-----------|----------------|------------------|-----------|-----------|
| Drop Array | 0.005s (2.60x NPZ, 0.16x NPY) | 0.007s (1.91x NPZ, 0.12x NPY) | 0.013s | 0.001s |
| Drop First Row | 0.019s (2.10x NPZ, 1.50x NPY) | 0.023s (1.67x NPZ, 1.20x NPY) | 0.039s | 0.028s |
| Drop Last Row | 0.019s (∞x NPZ, ∞x NPY) | 0.020s (∞x NPZ, ∞x NPY) | 0.039s | 0.028s |
| Drop Middle Row | 0.020s (2.00x NPZ, 1.43x NPY) | 0.020s (2.00x NPZ, 1.43x NPY) | 0.039s | 0.028s |
| Drop Front Continuous (10K rows) | 0.018s (2.11x NPZ, 1.52x NPY) | 0.021s (1.90x NPZ, 1.36x NPY) | 0.039s | 0.028s |
| Drop Middle Continuous (10K rows) | 0.019s (2.04x NPZ, 1.46x NPY) | 0.019s (2.04x NPZ, 1.46x NPY) | 0.039s | 0.028s |
| Drop End Continuous (10K rows) | 0.021s (1.87x NPZ, 1.34x NPY) | 0.021s (1.87x NPZ, 1.34x NPY) | 0.039s | 0.028s |
| Drop Random Rows (10K rows) | 0.022s (1.77x NPZ, 1.27x NPY) | 0.024s (1.63x NPZ, 1.17x NPY) | 0.039s | 0.028s |
| Drop Near Non-continuous (10K rows) | 0.021s (1.82x NPZ, 1.31x NPY) | 0.021s (1.82x NPZ, 1.31x NPY) | 0.039s | 0.028s |

#### Append Operations

| Operation | NumPack (Best) | NumPack (Python) | NumPy NPZ | NumPy NPY |
|-----------|----------------|------------------|-----------|-----------|
| Small Append (1K rows) | 0.004s (≥6x NPZ, ≥4x NPY) | 0.006s (≥5x NPZ, ≥3x NPY) | 0.028s | 0.018s |
| Large Append (500K rows) | 0.008s (4.86x NPZ, 3.06x NPY) | 0.008s (4.86x NPZ, 3.06x NPY) | 0.037s | 0.024s |

#### Random Access Performance (10K indices)

| Operation | NumPack (Best) | NumPack (Python) | NumPy NPZ | NumPy NPY |
|-----------|----------------|------------------|-----------|-----------|
| Random Access | 0.005s (2.13x NPZ, 1.54x NPY) | 0.005s (2.13x NPZ, 1.54x NPY) | 0.012s | 0.008s |

#### Matrix Computation Performance (1M rows x 128 columns, Float32)

| Operation | NumPack (Best) | NumPack (Python) | NumPy NPZ | NumPy NPY | In-Memory |
|-----------|----------------|------------------|-----------|-----------|-----------|
| Inner Product | 0.066s (2.18x NPZ, 6.23x Memory) | 0.066s (2.18x NPZ, 6.23x Memory) | 0.144s | 0.096s | 0.011s |

#### File Size Comparison

| Format | Size | Ratio |
|--------|------|-------|
| NumPack | 47.68 MB | 1.0x |
| NPZ | 47.68 MB | 1.0x |
| NPY | 47.68 MB | 1.0x |

> **Note**: Both Python and Rust backends generate identical file sizes as they use the same underlying file format.

#### Large-scale Data Operations (>1B rows, Float32)

| Operation | NumPack (Best) | NumPack (Python) | NumPy NPZ | NumPy NPY |
|-----------|----------------|------------------|-----------|-----------|
| Replace | Zero-copy in-place modification | Efficient in-place modification | Memory exceeded | Memory exceeded |
| Drop | Zero-copy in-place deletion | Efficient in-place deletion | Memory exceeded | Memory exceeded |
| Append | Zero-copy in-place addition | Efficient in-place addition | Memory exceeded | Memory exceeded |
| Random Access | Near-hardware I/O speed | High-performance I/O | Memory exceeded | Memory exceeded |

> **Key Advantage**: NumPack provides excellent matrix computation performance (0.066s vs 0.144s NPZ mmap) with several implementation advantages:
> - Uses Arc<Mmap> for reference counting, ensuring automatic resource cleanup
> - Implements MMAP_CACHE to avoid redundant data loading
> - Linux-specific optimizations with huge pages and sequential access hints
> - Supports parallel I/O operations for improved data throughput
> - Optimizes memory usage through Buffer Pool to reduce fragmentation

### Key Performance Highlights

1. **Data Modification**:
   - Single row replacement: NumPack Python backend is **≥156x faster** than NPZ and **≥90x faster** than NPY
   - Continuous rows: NumPack is **24x faster** than NPZ and **14x faster** than NPY
   - Random rows: NumPack is **1.71x faster** than NPZ and on par with NPY
   - Large data replacement: NumPack Python backend is **1.20x faster** than NPZ but **0.70x slower** than NPY

2. **Drop Operations**:
   - Drop array: NumPack Python backend is **1.91x faster** than NPZ
   - Drop rows: NumPack Python backend is **~2x faster** than NPZ and **~1.4x faster** than NPY in typical scenarios
   - NumPack continues to support efficient in-place row deletion without full file rewrite

3. **Append Operations**:
   - Small append (1K rows): NumPack Python backend is **≥5x faster** than NPZ and **≥3x faster** than NPY
   - Large append (500K rows): NumPack Python backend is **4.86x faster** than NPZ and **3.06x faster** than NPY
   - Performance improvements in append operations are attributed to optimized buffer management

4. **Loading Performance**:
   - Full load: NumPack Python backend is **1.56x faster** than NPZ and **0.85x slower** than NPY
   - Lazy load (memory-mapped): NumPack provides near-instantaneous loading
   - Selective load: NumPack Python backend is **1.61x faster** than NPZ

5. **Random Access**:
   - NumPack Python backend is **2.13x faster** than NPZ and **1.54x faster** than NPY for random index access

6. **Storage Efficiency**:
   - All formats achieve identical compression ratios (47.68 MB)
   - Both Python and Rust backends generate identical file sizes using the same underlying format

7. **Matrix Computation**:
   - NumPack Python backend provides **2.18x faster** performance than NPZ mmap
   - Only **6.23x slower** than pure in-memory computation, providing excellent balance of performance and memory efficiency
   - Zero risk of file descriptor leaks or resource exhaustion

8. **Backend Performance**:
   - **Python backend**: Excellent overall performance, particularly strong in modification operations
   - **Rust backend**: Optimized for specific use cases, with best-in-class performance for certain operations
   - Both backends share the same file format ensuring perfect compatibility

> Note: All benchmarks were performed with float32 arrays. Performance may vary depending on data types, array sizes, and system configurations. Numbers greater than 1.0x indicate faster performance, while numbers less than 1.0x indicate slower performance.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

This project is licensed under the Apache License, Version 2.0 - see the LICENSE file for details.

Copyright 2024 NumPack Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "numpack",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "numpy, array, storage, performance",
    "author": "NumPack Contributors",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/15/7a/1196f34ec39b623e48b7c79932524eb71d21647de5927d8a73a75fb17d08/numpack-0.2.1.tar.gz",
    "platform": null,
    "description": "# NumPack\n\nNumPack is a lightning-fast array manipulation engine that revolutionizes how you handle large-scale NumPy arrays. By combining Rust's raw performance with Python's ease of use, NumPack delivers up to 20x faster operations than traditional methods, while using minimal memory. Whether you're working with gigabyte-sized matrices or performing millions of array operations, NumPack makes it effortless with its zero-copy architecture and intelligent memory management.\n\nKey highlights:\n- \ud83d\ude80 Up to 20x faster than traditional NumPy storage methods\n- \ud83d\udcbe Zero-copy operations for minimal memory footprint\n- \ud83d\udd04 Seamless integration with existing NumPy workflows\n- \ud83d\udee0 Battle-tested in production with arrays exceeding 1 billion rows\n\n## Features\n\n- **High Performance**: Optimized for both reading and writing large numerical arrays\n- **Lazy Loading Support**: Efficient memory usage through on-demand data loading\n- **Selective Loading**: Load only the arrays you need, when you need them\n- **In-place Operations**: Support for in-place array modifications without full file rewrite\n- **Parallel I/O**: Utilizes parallel processing for improved performance\n- **Multiple Data Types**: Supports various numerical data types including:\n  - Boolean\n  - Unsigned integers (8-bit to 64-bit)\n  - Signed integers (8-bit to 64-bit)\n  - Floating point (32-bit and 64-bit)\n\n## Installation\n\n### From PyPI (Recommended)\n\n#### Prerequisites\n- Python >= 3.9\n- NumPy >= 1.26.0\n\n```bash\npip install numpack\n```\n\n### From Source\n\nTo build and install NumPack from source, you need to meet the following requirements:\n\n#### Prerequisites\n\n- Python >= 3.9\n- Rust >= 1.70.0\n- NumPy >= 1.26.0\n- Appropriate C/C++ compiler (depending on your operating system)\n  - Linux: GCC or Clang\n  - macOS: Clang (via Xcode Command Line Tools)\n  - Windows: MSVC (via Visual Studio or Build Tools)\n\n#### Build Steps\n\n1. Clone the repository:\n```bash\ngit clone https://github.com/BirchKwok/NumPack.git\ncd NumPack\n```\n\n2. Install maturin (for building Rust and Python hybrid projects):\n```bash\npip install maturin>=1.0,<2.0\n```\n\n3. Build and install:\n```bash\n# Install in development mode\nmaturin develop\n\n# Or build wheel package\nmaturin build --release\npip install target/wheels/numpack-*.whl\n```\n\n#### Platform-Specific Notes\n\n- **Linux Users**:\n  - Ensure python3-dev (Ubuntu/Debian) or python3-devel (Fedora/RHEL) is installed\n  - If using conda environment, make sure the appropriate compiler toolchain is installed\n\n- **macOS Users**:\n  - Make sure Xcode Command Line Tools are installed: `xcode-select --install`\n  - Supports both Intel and Apple Silicon architectures\n\n- **Windows Users**:\n  - Visual Studio or Visual Studio Build Tools required\n  - Ensure \"Desktop development with C++\" workload is installed\n\n\n## Usage\n\n### Basic Operations\n\n```python\nimport numpy as np\nfrom numpack import NumPack\n\n# Create a NumPack instance\nnpk = NumPack(\"data_directory\")\n\n# Save arrays\narrays = {\n    'array1': np.random.rand(1000, 100).astype(np.float32),\n    'array2': np.random.rand(500, 200).astype(np.float32)\n}\nnpk.save(arrays)\n\n# Load arrays\n# Normal mode\nloaded = npk.load(\"array1\")\n\n# lazy load\nlazy_array = npk.load(\"arr1\", lazy=True)\n```\n\n### Advanced Operations\n\n```python\n# Replace specific rows\nreplacement = np.random.rand(10, 100).astype(np.float32)\nnpk.replace({'array1': replacement}, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])  # Using list indices\nnpk.replace({'array1': replacement}, slice(0, 10))  # Using slice notation\n\n# Append new arrays\nnew_arrays = {\n    'array3': np.random.rand(200, 100).astype(np.float32)\n}\nnpk.append(new_arrays)\n\n# Drop arrays or specific rows\nnpk.drop('array1')  # Drop entire array\nnpk.drop(['array1', 'array2'])  # Drop multiple arrays\nnpk.drop('array2', [0, 1, 2])  # Drop specific rows\n\n# Random access operations\ndata = npk.getitem('array1', [0, 1, 2])  # Access specific rows\ndata = npk.getitem('array1', slice(0, 10))  # Access using slice\ndata = npk['array1']  # Dictionary-style access for entire array\n\n# Metadata operations\nshapes = npk.get_shape()  # Get shapes of all arrays\nshapes = npk.get_shape('array1')  # Get shape of specific array\nmembers = npk.get_member_list()  # Get list of array names\nmtime = npk.get_modify_time('array1')  # Get modification time\nmetadata = npk.get_metadata()  # Get complete metadata\n\n# Stream loading for large arrays\nfor batch in npk.stream_load('array1', buffer_size=1000):\n    # Process 1000 rows at a time\n    process_batch(batch)\n\n# Reset/clear storage\nnpk.reset()  # Clear all arrays\n\n# Iterate over all arrays\nfor array_name in npk:\n    data = npk[array_name]\n    print(f\"{array_name} shape: {data.shape}\")\n```\n\n### Lazy Loading and Buffer Operations\n\nNumPack supports lazy loading and buffer operations, which are particularly useful for handling large-scale datasets. Using the `lazy=True` parameter enables data to be loaded only when actually needed, making it ideal for streaming processing or scenarios where only partial data access is required.\n\n```python\nfrom numpack import NumPack\nimport numpy as np\n\n# Create NumPack instance and save large-scale data\nnpk = NumPack(\"test_data/\", drop_if_exists=True)\na = np.random.random((1000000, 128))  # Create a large array\nnpk.save({\"arr1\": a})\n\n# Lazy loading - keeps data in buffer\nlazy_array = npk.load(\"arr1\", lazy=True)  # LazyArray Object\n\n# Perform computations with lazy-loaded data\n# Only required data is loaded into memory\nsimilarity_scores = np.inner(a[0], npk.load(\"arr1\", lazy=True))\n```\n\n## Performance\n\nNumPack offers significant performance improvements compared to traditional NumPy storage methods, especially in data modification operations and random access. Below are detailed benchmark results:\n\n### Benchmark Results\n\nThe following benchmarks were performed on an MacBook Pro (Apple Silicon) with arrays of size 1M x 10 and 500K x 5 (float32).\n\n#### Storage Operations\n\n| Operation | NumPack (Best) | NumPack (Python) | NumPy NPZ | NumPy NPY |\n|-----------|----------------|------------------|-----------|-----------|\n| Save | 0.015s (0.96x NPZ, 0.55x NPY) | 0.015s (0.96x NPZ, 0.55x NPY) | 0.014s | 0.008s |\n| Full Load | 0.007s (1.89x NPZ, 1.02x NPY) | 0.009s (1.56x NPZ, 0.85x NPY) | 0.014s | 0.008s |\n| Selective Load | 0.006s (1.61x NPZ, -) | 0.006s (1.61x NPZ, -) | 0.010s | - |\n\n#### Data Modification Operations\n\n| Operation | NumPack (Best) | NumPack (Python) | NumPy NPZ | NumPy NPY |\n|-----------|----------------|------------------|-----------|-----------|\n| Single Row Replace | 0.000s (\u2265156x NPZ, \u226590x NPY) | 0.000s (\u2265156x NPZ, \u226590x NPY) | 0.024s | 0.014s |\n| Continuous Rows (10K) | 0.001s (24.00x NPZ, 14.00x NPY) | 0.001s (24.00x NPZ, 14.00x NPY) | 0.024s | 0.014s |\n| Random Rows (10K) | 0.014s (1.71x NPZ, 1.00x NPY) | 0.014s (1.71x NPZ, 1.00x NPY) | 0.024s | 0.014s |\n| Large Data Replace (500K) | 0.018s (1.33x NPZ, 0.78x NPY) | 0.020s (1.20x NPZ, 0.70x NPY) | 0.024s | 0.014s |\n\n#### Drop Operations\n\n| Operation (1M rows, float32) | NumPack (Best) | NumPack (Python) | NumPy NPZ | NumPy NPY |\n|-----------|----------------|------------------|-----------|-----------|\n| Drop Array | 0.005s (2.60x NPZ, 0.16x NPY) | 0.007s (1.91x NPZ, 0.12x NPY) | 0.013s | 0.001s |\n| Drop First Row | 0.019s (2.10x NPZ, 1.50x NPY) | 0.023s (1.67x NPZ, 1.20x NPY) | 0.039s | 0.028s |\n| Drop Last Row | 0.019s (\u221ex NPZ, \u221ex NPY) | 0.020s (\u221ex NPZ, \u221ex NPY) | 0.039s | 0.028s |\n| Drop Middle Row | 0.020s (2.00x NPZ, 1.43x NPY) | 0.020s (2.00x NPZ, 1.43x NPY) | 0.039s | 0.028s |\n| Drop Front Continuous (10K rows) | 0.018s (2.11x NPZ, 1.52x NPY) | 0.021s (1.90x NPZ, 1.36x NPY) | 0.039s | 0.028s |\n| Drop Middle Continuous (10K rows) | 0.019s (2.04x NPZ, 1.46x NPY) | 0.019s (2.04x NPZ, 1.46x NPY) | 0.039s | 0.028s |\n| Drop End Continuous (10K rows) | 0.021s (1.87x NPZ, 1.34x NPY) | 0.021s (1.87x NPZ, 1.34x NPY) | 0.039s | 0.028s |\n| Drop Random Rows (10K rows) | 0.022s (1.77x NPZ, 1.27x NPY) | 0.024s (1.63x NPZ, 1.17x NPY) | 0.039s | 0.028s |\n| Drop Near Non-continuous (10K rows) | 0.021s (1.82x NPZ, 1.31x NPY) | 0.021s (1.82x NPZ, 1.31x NPY) | 0.039s | 0.028s |\n\n#### Append Operations\n\n| Operation | NumPack (Best) | NumPack (Python) | NumPy NPZ | NumPy NPY |\n|-----------|----------------|------------------|-----------|-----------|\n| Small Append (1K rows) | 0.004s (\u22656x NPZ, \u22654x NPY) | 0.006s (\u22655x NPZ, \u22653x NPY) | 0.028s | 0.018s |\n| Large Append (500K rows) | 0.008s (4.86x NPZ, 3.06x NPY) | 0.008s (4.86x NPZ, 3.06x NPY) | 0.037s | 0.024s |\n\n#### Random Access Performance (10K indices)\n\n| Operation | NumPack (Best) | NumPack (Python) | NumPy NPZ | NumPy NPY |\n|-----------|----------------|------------------|-----------|-----------|\n| Random Access | 0.005s (2.13x NPZ, 1.54x NPY) | 0.005s (2.13x NPZ, 1.54x NPY) | 0.012s | 0.008s |\n\n#### Matrix Computation Performance (1M rows x 128 columns, Float32)\n\n| Operation | NumPack (Best) | NumPack (Python) | NumPy NPZ | NumPy NPY | In-Memory |\n|-----------|----------------|------------------|-----------|-----------|-----------|\n| Inner Product | 0.066s (2.18x NPZ, 6.23x Memory) | 0.066s (2.18x NPZ, 6.23x Memory) | 0.144s | 0.096s | 0.011s |\n\n#### File Size Comparison\n\n| Format | Size | Ratio |\n|--------|------|-------|\n| NumPack | 47.68 MB | 1.0x |\n| NPZ | 47.68 MB | 1.0x |\n| NPY | 47.68 MB | 1.0x |\n\n> **Note**: Both Python and Rust backends generate identical file sizes as they use the same underlying file format.\n\n#### Large-scale Data Operations (>1B rows, Float32)\n\n| Operation | NumPack (Best) | NumPack (Python) | NumPy NPZ | NumPy NPY |\n|-----------|----------------|------------------|-----------|-----------|\n| Replace | Zero-copy in-place modification | Efficient in-place modification | Memory exceeded | Memory exceeded |\n| Drop | Zero-copy in-place deletion | Efficient in-place deletion | Memory exceeded | Memory exceeded |\n| Append | Zero-copy in-place addition | Efficient in-place addition | Memory exceeded | Memory exceeded |\n| Random Access | Near-hardware I/O speed | High-performance I/O | Memory exceeded | Memory exceeded |\n\n> **Key Advantage**: NumPack provides excellent matrix computation performance (0.066s vs 0.144s NPZ mmap) with several implementation advantages:\n> - Uses Arc<Mmap> for reference counting, ensuring automatic resource cleanup\n> - Implements MMAP_CACHE to avoid redundant data loading\n> - Linux-specific optimizations with huge pages and sequential access hints\n> - Supports parallel I/O operations for improved data throughput\n> - Optimizes memory usage through Buffer Pool to reduce fragmentation\n\n### Key Performance Highlights\n\n1. **Data Modification**:\n   - Single row replacement: NumPack Python backend is **\u2265156x faster** than NPZ and **\u226590x faster** than NPY\n   - Continuous rows: NumPack is **24x faster** than NPZ and **14x faster** than NPY\n   - Random rows: NumPack is **1.71x faster** than NPZ and on par with NPY\n   - Large data replacement: NumPack Python backend is **1.20x faster** than NPZ but **0.70x slower** than NPY\n\n2. **Drop Operations**:\n   - Drop array: NumPack Python backend is **1.91x faster** than NPZ\n   - Drop rows: NumPack Python backend is **~2x faster** than NPZ and **~1.4x faster** than NPY in typical scenarios\n   - NumPack continues to support efficient in-place row deletion without full file rewrite\n\n3. **Append Operations**:\n   - Small append (1K rows): NumPack Python backend is **\u22655x faster** than NPZ and **\u22653x faster** than NPY\n   - Large append (500K rows): NumPack Python backend is **4.86x faster** than NPZ and **3.06x faster** than NPY\n   - Performance improvements in append operations are attributed to optimized buffer management\n\n4. **Loading Performance**:\n   - Full load: NumPack Python backend is **1.56x faster** than NPZ and **0.85x slower** than NPY\n   - Lazy load (memory-mapped): NumPack provides near-instantaneous loading\n   - Selective load: NumPack Python backend is **1.61x faster** than NPZ\n\n5. **Random Access**:\n   - NumPack Python backend is **2.13x faster** than NPZ and **1.54x faster** than NPY for random index access\n\n6. **Storage Efficiency**:\n   - All formats achieve identical compression ratios (47.68 MB)\n   - Both Python and Rust backends generate identical file sizes using the same underlying format\n\n7. **Matrix Computation**:\n   - NumPack Python backend provides **2.18x faster** performance than NPZ mmap\n   - Only **6.23x slower** than pure in-memory computation, providing excellent balance of performance and memory efficiency\n   - Zero risk of file descriptor leaks or resource exhaustion\n\n8. **Backend Performance**:\n   - **Python backend**: Excellent overall performance, particularly strong in modification operations\n   - **Rust backend**: Optimized for specific use cases, with best-in-class performance for certain operations\n   - Both backends share the same file format ensuring perfect compatibility\n\n> Note: All benchmarks were performed with float32 arrays. Performance may vary depending on data types, array sizes, and system configurations. Numbers greater than 1.0x indicate faster performance, while numbers less than 1.0x indicate slower performance.\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\nThis project is licensed under the Apache License, Version 2.0 - see the LICENSE file for details.\n\nCopyright 2024 NumPack Contributors\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A high-performance array storage and manipulation library",
    "version": "0.2.1",
    "project_urls": null,
    "split_keywords": [
        "numpy",
        " array",
        " storage",
        " performance"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "56ef58d3a91165bffbbede1cc302419bc4dd469262e735fd7b587892df3b173b",
                "md5": "ab9f9c9df315f6480d036fce63320382",
                "sha256": "766ba4be20a548e3d7798212bb7fa16406c6ca2e6a16334674b9c9c2ff7fbdcd"
            },
            "downloads": -1,
            "filename": "numpack-0.2.1-cp310-cp310-macosx_10_12_x86_64.whl",
            "has_sig": false,
            "md5_digest": "ab9f9c9df315f6480d036fce63320382",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.9",
            "size": 766111,
            "upload_time": "2025-07-22T16:35:08",
            "upload_time_iso_8601": "2025-07-22T16:35:08.206538Z",
            "url": "https://files.pythonhosted.org/packages/56/ef/58d3a91165bffbbede1cc302419bc4dd469262e735fd7b587892df3b173b/numpack-0.2.1-cp310-cp310-macosx_10_12_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "3e8bc4d98e98a5e286e144dd37f779f3d02bc032628475fc2d75e24a4a11b0c8",
                "md5": "9c1e6c84254723fe3a236916252a490b",
                "sha256": "5efb6a9f3e8fb93a86ad3e530291f2d582681d4a148283181b5d562ce115f9a0"
            },
            "downloads": -1,
            "filename": "numpack-0.2.1-cp310-cp310-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "9c1e6c84254723fe3a236916252a490b",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.9",
            "size": 731107,
            "upload_time": "2025-07-22T16:35:09",
            "upload_time_iso_8601": "2025-07-22T16:35:09.832862Z",
            "url": "https://files.pythonhosted.org/packages/3e/8b/c4d98e98a5e286e144dd37f779f3d02bc032628475fc2d75e24a4a11b0c8/numpack-0.2.1-cp310-cp310-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "6887a677d75c0c99fdfecdfafd3ee5b6bc02fd3e7e6f711b152856f446b147b3",
                "md5": "7e2d26056dbc75ad05ac883f13f5dd17",
                "sha256": "da54acd5b69dc0109c9216a2e821f08f3a3cd707a4fb75b5dae5c22e870dce7c"
            },
            "downloads": -1,
            "filename": "numpack-0.2.1-cp310-cp310-manylinux_2_34_x86_64.whl",
            "has_sig": false,
            "md5_digest": "7e2d26056dbc75ad05ac883f13f5dd17",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.9",
            "size": 807797,
            "upload_time": "2025-07-22T16:35:11",
            "upload_time_iso_8601": "2025-07-22T16:35:11.166318Z",
            "url": "https://files.pythonhosted.org/packages/68/87/a677d75c0c99fdfecdfafd3ee5b6bc02fd3e7e6f711b152856f446b147b3/numpack-0.2.1-cp310-cp310-manylinux_2_34_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "7ea6140a588696c2315ab367a50629ff041702eaf794376e0d07b06c915dcb26",
                "md5": "bcf1dada44e03109b3b2bc6cdad04ecb",
                "sha256": "a6b190fb3033c82409a50d618e9823154ee1ccc149d8bf4b412d2bee460c1a51"
            },
            "downloads": -1,
            "filename": "numpack-0.2.1-cp311-cp311-macosx_10_12_x86_64.whl",
            "has_sig": false,
            "md5_digest": "bcf1dada44e03109b3b2bc6cdad04ecb",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.9",
            "size": 765618,
            "upload_time": "2025-07-22T16:35:12",
            "upload_time_iso_8601": "2025-07-22T16:35:12.283180Z",
            "url": "https://files.pythonhosted.org/packages/7e/a6/140a588696c2315ab367a50629ff041702eaf794376e0d07b06c915dcb26/numpack-0.2.1-cp311-cp311-macosx_10_12_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "60fbc7870640ff87377209657d01616826a3a25ecba3d658ff500551ca85e0eb",
                "md5": "ef915e690789e81217d2b6cafd7c0514",
                "sha256": "042ae3a9b9279ee6299ebb69dc33094df75f68b7e3a8ffe25317048ce364225e"
            },
            "downloads": -1,
            "filename": "numpack-0.2.1-cp311-cp311-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "ef915e690789e81217d2b6cafd7c0514",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.9",
            "size": 731130,
            "upload_time": "2025-07-22T16:35:13",
            "upload_time_iso_8601": "2025-07-22T16:35:13.583103Z",
            "url": "https://files.pythonhosted.org/packages/60/fb/c7870640ff87377209657d01616826a3a25ecba3d658ff500551ca85e0eb/numpack-0.2.1-cp311-cp311-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "e789aa35c69ca65c64f281dafce54770081c5e8b8493944fcdcf1a03c69a22ff",
                "md5": "f2865a3afbfc51398552d8e25ae2c379",
                "sha256": "1ffa8ecf4b49d7e100c5ac625346de895eb2c7d355284b1d0d70b79a3dfc5c08"
            },
            "downloads": -1,
            "filename": "numpack-0.2.1-cp311-cp311-manylinux_2_34_x86_64.whl",
            "has_sig": false,
            "md5_digest": "f2865a3afbfc51398552d8e25ae2c379",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.9",
            "size": 807259,
            "upload_time": "2025-07-22T16:35:14",
            "upload_time_iso_8601": "2025-07-22T16:35:14.910841Z",
            "url": "https://files.pythonhosted.org/packages/e7/89/aa35c69ca65c64f281dafce54770081c5e8b8493944fcdcf1a03c69a22ff/numpack-0.2.1-cp311-cp311-manylinux_2_34_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "1ec61fd7e6a9f545ef002aceadead470dbeffd25ee391e8b203c712cb0a1cf6b",
                "md5": "7d8c6d7f154d1b2ec64f7d48801a8f74",
                "sha256": "187e5a19b5bb5c8d71f8862ab48e36fdcf5a81853885687aca41e634b28fbdeb"
            },
            "downloads": -1,
            "filename": "numpack-0.2.1-cp312-cp312-macosx_10_12_x86_64.whl",
            "has_sig": false,
            "md5_digest": "7d8c6d7f154d1b2ec64f7d48801a8f74",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.9",
            "size": 759954,
            "upload_time": "2025-07-22T16:35:16",
            "upload_time_iso_8601": "2025-07-22T16:35:16.249458Z",
            "url": "https://files.pythonhosted.org/packages/1e/c6/1fd7e6a9f545ef002aceadead470dbeffd25ee391e8b203c712cb0a1cf6b/numpack-0.2.1-cp312-cp312-macosx_10_12_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "c29e1e3a04f613539c62640a1fab18115291704b387709482458882b502a96b6",
                "md5": "28b7540642f6c74e924904c7cd66a315",
                "sha256": "3fb929316eba76b422ba6a5a8eb7c33a964dd64075bc2cc20731f000ade8ee1f"
            },
            "downloads": -1,
            "filename": "numpack-0.2.1-cp312-cp312-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "28b7540642f6c74e924904c7cd66a315",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.9",
            "size": 726987,
            "upload_time": "2025-07-22T16:35:17",
            "upload_time_iso_8601": "2025-07-22T16:35:17.469764Z",
            "url": "https://files.pythonhosted.org/packages/c2/9e/1e3a04f613539c62640a1fab18115291704b387709482458882b502a96b6/numpack-0.2.1-cp312-cp312-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "fe68fabd3b3ae49ba767f67e55807514045d8f199be18175a7190ba8bfdac2a5",
                "md5": "2e9d7f8692e8c1a664c7594d6491a20f",
                "sha256": "b2177ab4cd0cab610f7d19033db8530e5fd705eb0e7d73c13270cb7994d02cad"
            },
            "downloads": -1,
            "filename": "numpack-0.2.1-cp312-cp312-manylinux_2_34_x86_64.whl",
            "has_sig": false,
            "md5_digest": "2e9d7f8692e8c1a664c7594d6491a20f",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.9",
            "size": 807848,
            "upload_time": "2025-07-22T16:35:18",
            "upload_time_iso_8601": "2025-07-22T16:35:18.712126Z",
            "url": "https://files.pythonhosted.org/packages/fe/68/fabd3b3ae49ba767f67e55807514045d8f199be18175a7190ba8bfdac2a5/numpack-0.2.1-cp312-cp312-manylinux_2_34_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "fdab9ab617215110893da8b213ccd5d007db17e0032e5f28abf12654cc5fb256",
                "md5": "d085080bf78959bb2b7e97825700ee6b",
                "sha256": "20a80a44d46745ea764b639a7cf13a649101e0681a27b712411a4168e99078b8"
            },
            "downloads": -1,
            "filename": "numpack-0.2.1-cp313-cp313-macosx_10_12_x86_64.whl",
            "has_sig": false,
            "md5_digest": "d085080bf78959bb2b7e97825700ee6b",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": ">=3.9",
            "size": 759149,
            "upload_time": "2025-07-22T16:35:20",
            "upload_time_iso_8601": "2025-07-22T16:35:20.059913Z",
            "url": "https://files.pythonhosted.org/packages/fd/ab/9ab617215110893da8b213ccd5d007db17e0032e5f28abf12654cc5fb256/numpack-0.2.1-cp313-cp313-macosx_10_12_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "09b001cedec570d08de4489adb21b8549c361070d936048eec819ff4cc0c77be",
                "md5": "48a05521d2c2a02a39097b016e818a0d",
                "sha256": "bda93ebd75ef6b5e9304d0b037bcba198bac802a2e7c64ebec453c3b9d95d0fe"
            },
            "downloads": -1,
            "filename": "numpack-0.2.1-cp313-cp313-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "48a05521d2c2a02a39097b016e818a0d",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": ">=3.9",
            "size": 726337,
            "upload_time": "2025-07-22T16:35:21",
            "upload_time_iso_8601": "2025-07-22T16:35:21.417373Z",
            "url": "https://files.pythonhosted.org/packages/09/b0/01cedec570d08de4489adb21b8549c361070d936048eec819ff4cc0c77be/numpack-0.2.1-cp313-cp313-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "a21557f38b5552ce4cd0873716e3804066201bf36639fef57b1e76fc239aaaaf",
                "md5": "047b7bf579f649e6b2a5e1f29fcbbfe7",
                "sha256": "ce15cef988332b2db4aeaea68ed15635f38af3d2b7bb9aa4791ad4ec75e5aaa3"
            },
            "downloads": -1,
            "filename": "numpack-0.2.1-cp313-cp313-manylinux_2_34_x86_64.whl",
            "has_sig": false,
            "md5_digest": "047b7bf579f649e6b2a5e1f29fcbbfe7",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": ">=3.9",
            "size": 807482,
            "upload_time": "2025-07-22T16:35:22",
            "upload_time_iso_8601": "2025-07-22T16:35:22.698079Z",
            "url": "https://files.pythonhosted.org/packages/a2/15/57f38b5552ce4cd0873716e3804066201bf36639fef57b1e76fc239aaaaf/numpack-0.2.1-cp313-cp313-manylinux_2_34_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "89446fda894f13f3d48a4719c22339db6369e04c15f16ee0eece91d3846a52ab",
                "md5": "2f50c085b6e88490b110d3706f434b63",
                "sha256": "a0a2c145a98bb120ce8a05db7975550e639b8f0ce8916f3ea4115320fb7760d4"
            },
            "downloads": -1,
            "filename": "numpack-0.2.1-cp39-cp39-macosx_10_12_x86_64.whl",
            "has_sig": false,
            "md5_digest": "2f50c085b6e88490b110d3706f434b63",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.9",
            "size": 766619,
            "upload_time": "2025-07-22T16:35:23",
            "upload_time_iso_8601": "2025-07-22T16:35:23.711561Z",
            "url": "https://files.pythonhosted.org/packages/89/44/6fda894f13f3d48a4719c22339db6369e04c15f16ee0eece91d3846a52ab/numpack-0.2.1-cp39-cp39-macosx_10_12_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "d268b576b6ae2719f762ef20bf18a25d0a88733d2024572b91670079320e9eb5",
                "md5": "0682b829f34a31a0c97f3fb70ea327f0",
                "sha256": "f7853c59dde3a30a15db6fb9917a28be06022cf2dd4afdc3a70c3d9e83237736"
            },
            "downloads": -1,
            "filename": "numpack-0.2.1-cp39-cp39-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "0682b829f34a31a0c97f3fb70ea327f0",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.9",
            "size": 731317,
            "upload_time": "2025-07-22T16:35:25",
            "upload_time_iso_8601": "2025-07-22T16:35:25.035495Z",
            "url": "https://files.pythonhosted.org/packages/d2/68/b576b6ae2719f762ef20bf18a25d0a88733d2024572b91670079320e9eb5/numpack-0.2.1-cp39-cp39-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5f600d2ebe5af7c71b95239ac2c7453eacca7edb41c1f29df50c49b127d2aecb",
                "md5": "62b2d57116c268100c0bb19a02e7b0a7",
                "sha256": "c7c32d32d6bb1c020abc89b95f135514967081240b2000fba353d98ad41f44e3"
            },
            "downloads": -1,
            "filename": "numpack-0.2.1-cp39-cp39-manylinux_2_34_x86_64.whl",
            "has_sig": false,
            "md5_digest": "62b2d57116c268100c0bb19a02e7b0a7",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.9",
            "size": 808344,
            "upload_time": "2025-07-22T16:35:26",
            "upload_time_iso_8601": "2025-07-22T16:35:26.117255Z",
            "url": "https://files.pythonhosted.org/packages/5f/60/0d2ebe5af7c71b95239ac2c7453eacca7edb41c1f29df50c49b127d2aecb/numpack-0.2.1-cp39-cp39-manylinux_2_34_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "da322aff1282102849e6b074d85fb40363114ea17536f675a6506d0e6ba73f2e",
                "md5": "0254418627b8edc8ba41661c3d202705",
                "sha256": "1e6f7c7464cd3dc343d44a51ee595dae7188705be70fae636aed28764eb6f039"
            },
            "downloads": -1,
            "filename": "numpack-0.2.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "0254418627b8edc8ba41661c3d202705",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 60816,
            "upload_time": "2025-07-22T16:35:27",
            "upload_time_iso_8601": "2025-07-22T16:35:27.146449Z",
            "url": "https://files.pythonhosted.org/packages/da/32/2aff1282102849e6b074d85fb40363114ea17536f675a6506d0e6ba73f2e/numpack-0.2.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "157a1196f34ec39b623e48b7c79932524eb71d21647de5927d8a73a75fb17d08",
                "md5": "f99d966cd0bf274b4f8031afa4329109",
                "sha256": "4a06dbc6c10d5d34cb2e7ebd4cda2b126d10cdafa8953cfa9395c9104c529714"
            },
            "downloads": -1,
            "filename": "numpack-0.2.1.tar.gz",
            "has_sig": false,
            "md5_digest": "f99d966cd0bf274b4f8031afa4329109",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 60661,
            "upload_time": "2025-07-22T16:35:27",
            "upload_time_iso_8601": "2025-07-22T16:35:27.909276Z",
            "url": "https://files.pythonhosted.org/packages/15/7a/1196f34ec39b623e48b7c79932524eb71d21647de5927d8a73a75fb17d08/numpack-0.2.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-22 16:35:27",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "numpack"
}
        
Elapsed time: 1.10679s