Skip to main content

i38e-utils

i38e-utils is a collection of utility functions and classes that I use in my BI projects. It is a work in progress and will be updated as I add more functionality.

The utilities are designed to work with Django, OpenStreetMaps and NetworkX

Currently, it includes the following:

  1. DfHelper: A class designed to facilitate data handling and operations within a Django project, particularly focusing on loading data from both parquet files and a database, and potentially saving data to parquet format.
  2. GeoLocationService: A class that provides a set of utility functions for working with GeoPy and Nominatim.
  3. OsmxHelper: A class that provides a set of utility functions for working with Osmnx maps.
  4. data_utils: A set of utility functions/classes for working with data.
  5. date_utils: A set of utility functions for working with dates.
  6. df_utils: A set of utility functions for working with pandas DataFrames.
  7. file_utils: A set of utility functions for working with files.
  8. log_utils: A set of utility functions for working with logs.

Installation

To install this project, follow these steps:

pip install i38e-utils

Usage

DfHelper: Dataframe Helper Class

DfHelper is designed to be subclassed. For example, the following use case, connects to a table containing gps transactions and encapsulates data cleaning operations. The resulting object can be queried via the "load" method using Django's query language syntax. The object can also be instantiated in debug and verbose mode.

The object returns Dataframe objects either as pandas (by default) or dask. It is recommended to use dask for large datasets which may benefit from dask parallelization architecture. Scenarios:

  • Connect to a database table using a Django's ORM connection, query, transform and convert the data to a pandas DataFrame.
import pandas as pd
import numpy as np
from i38e_utils.df_helper import DfHelper

phone_mobile_gps_fields = {
    'id_tracking': 'id',
    'id_producto': 'product_id',
    'pk_empleado': 'associate_id',
    'latitud': 'latitude',
    'longitud': 'longitude',
    'fecha_hora_servidor': 'server_dt',
    'fecha_hora': 'date_time',
    'accion': 'action',
    'descripcion': 'description',
    'imei': 'imei'
}


class GpsCube(DfHelper):
    df: pd.DataFrame = None
    live: bool = False
    save_parquet = True
    
    config={
        'connection_name': 'replica',
        'table': 'asm_tracking_movil_gps',
        'field_map': phone_mobile_gps_fields,
        'legacy_filters': True,
    }

    def __init__(self, **opts):
        config = {**self.config, **opts}
        super().__init__(**config)
        
    def load(self, **kwargs):
        self.df = super().load(**kwargs)
        self.fix_data()
        return self.df

    def fix_data(self):
        self.df['latitude'] = self.df['latitude'].astype(np.float64)
        self.df['longitude'] = self.df['longitude'].astype(np.float64)```python

gps_cube=GpsCube(live=True, debug=False,df_as_dask=True)
df=gps_cube.load(date_time__date='2023-03-04').compute()
# to save to a parquet file
gps_cube.save_to_parquet(df, parquet_full_path='gpscube.parquet')
  • Use a parquet storage file or folder structure to load data and perform some transformations.
import pandas as pd
from i38e_utils.df_helper import DfHelper

class GpsParquetCube(DfHelper):
    df: pd.DataFrame = None
    
    config={
        'use_parquet': True,
        'df_as_dask': True,
        'parquet_storage_path': '/storage/data/parquet/gps',
        'parquet_start_date': '2024-01-01',
        'parquet_end_date': '2024-03-31',
    }

    def __init__(self, **opts):
        config = {**self.config, **opts}
        super().__init__(**config)
        
    def load(self, **kwargs):
        self.df = super().load(**kwargs)
        return self.df


# The following example would load all the parquet files in the folder structure described in parquet_storage_path matching the date range and return a single dask dataframe for associate_id 27 for the month of March.
# The class converts Django style filters to dask compatible filters.
# The class also converts the parquet files to a dask dataframe for faster processing.

params = {
    'associate_id': 27,
    'date_time__date__range': ['2024-03-01','2024-03-31']
}

dask_df = GpsParquetCube().load(**params)
# to convert to a pandas dataframe
df = dask_df.compute()

Usage

osmnx_helper: Base Map and Utilities

Use case: Create a heat map with time using a DfHelper cube with gps data

from i38e_utils.osmnx_helper import BaseOsmMap
from i38e_utils.osmnx_helper.utils import get_graph
import folium

options = {
    'ox_files_save_path': 'path/to/pbf/files',
    'network_type': 'all',
    'place': 'Costa Rica',
    'files_prefix': 'costa-rica-',
    'rebuild': False,
    'verbose': False
}

class ActivityHeatMapWithTime(BaseOsmMap):
    def __init__(self, df, **kwargs):
        kwargs.setdefault('dt_field', 'date_time')
        G, _, _ = get_graph(**options)
        self.heat_time_index = []
        super().__init__(G, df, **kwargs)

    def process_map(self):
        self.heat_time_index = sorted(list(self.df[self.dt_field].dt.hour.unique()))
        heat_data_time = [[[row[self.lat_col], row[self.lon_col]] for index, row in
                           self.df[self.df[self.dt_field].apply(lambda x: x.hour == j)].iterrows()] for j in self.heat_time_index]

        hm = folium.plugins.HeatMapWithTime(heat_data_time, index=self.heat_time_index)
        # hm = HeatMap(gps_points)
        hm.add_to(self.osm_map)

to create a heatmap using a Dataframe of GPS Data

df=GpsCube().load(date_time__date="2024-06-30")
map_options={}
map_options.setdefault("map_html_title","Activity Heatmap")
map_options.setdefault("dt_field", "date_time")
map_options.setdefault("max_bounds", False)
heat_map=ActivityHeatMapWithTime(df, **map_options)
heat_map.generate_map()

Metadata

Release files for i38e-utils 1.0.48

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for i38e-utils 1.0.48
File Size Uploaded Provenance Actions
i38e_utils-1.0.48.tar.gz 34.4 kB Without provenance Details for i38e_utils-1.0.48.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for i38e-utils 1.0.48
File Interpreter ABI Platform Actions
i38e_utils-1.0.48-py3-none-any.whl Python 3 none any Details for i38e_utils-1.0.48-py3-none-any.whl

Total release size: 74.3 kB

Release files / i38e_utils-1.0.48.tar.gz

Download URL i38e_utils-1.0.48.tar.gz
Size 34.4 kB
Tags Source
SHA-256 checksum
How to use checksums
c5c7825975bb4e71649dca2f3acf6771c4eb55eab2cb2db4ce6a39e3b304492b
BLAKE2b-256 checksum
How to use checksums
1e2c8b5ac66637ccda006b4edba0fddfd982af58e80541d727339cd6135e6bb5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.8.2 CPython/3.11.2 Darwin/24.0.0

Release files / i38e_utils-1.0.48-py3-none-any.whl

Download URL i38e_utils-1.0.48-py3-none-any.whl
Size 40.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a9b9d840a4468b0b4da79aaf08815e43bb0dd0d3b572f0bbdf282c523c1cbc54
BLAKE2b-256 checksum
How to use checksums
30e506a3ee694a73f1a050710cc9711bf4afe6d41fae2466699ea3e57ab815a6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.8.2 CPython/3.11.2 Darwin/24.0.0

Security for i38e-utils 1.0.48

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.48 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page