Skip to main content

A simple library to calculate price elasticity, cross elasticity

Project description

Retail Stats

Codacy Badge Build Status Coverage Status PyPI version shields.io PyPI pyversions PyPI license

This repository contains code to calculate various values used in retail for products whose sales and prices are provided.

Metrics currently available:

  1. Price Elasticity (In Progress)
  2. Cross Elasticity (Complete)

These simple, almost naive, implementations are taken from the Wikipedia definitions of the metrics. All performance benefits are from the work of Numpy. The purpose of this repository is to provide some convenience functions.

Installation

Install from PyPi.

pip install retail-stats

If installing outside of a [virtualenv]() then use --user to avoid permission issues:

pip install --user retail-stats

Dependencies

  1. numpy~=1.19

Calculations

Cross Elasticity

From Wikipedia,

measures the responsiveness of the quantity demanded for a good to a change in the price of another good, ceteris paribus.

This can be seen written using the formula:

Percentage Change in Quantity Sold of Product B
-------------------------------------------------
Percentage Change in Price Charged for Product A

The implementation is a direct copy of the formula.

from retail_stats.elasticity import calculate_cross_elasticity

Calculate Cross Elasticity for a single pair of products

from math import isclose
from retail_stats import elasticity

original_quantity = 200
new_quantity = 400

original_price = 1000
new_price = 1050
# (200 / 300) / (50 / 1025)
expected_ced = 13.66666666666666
ced = elasticity.calculate_cross_elasticity(original_quantity, 
                                            new_quantity, 
                                            original_price, 
                                            new_price)

assert isclose(expected_ced, ced)

Calculate All Cross Elasticities

from math import isclose

import numpy as np

from retail_stats.elasticity import get_all_cross_elasticities

skus = np.array(list("ABCD"))
# [original, new]
qty_a = [200, 0]
qty_b = [200, 400]
prc_a = [1000, 1050]
prc_b = [1000, 1000]

qty_c = [1000, 1050]
qty_d = [1000, 1100]
prc_c = [100, 80]
prc_d = [80, 80]

original_quantities = [qty_a[0], qty_b[0], qty_c[0], qty_d[0]]
new_quantities = [qty_a[1], qty_b[1], qty_c[1], qty_d[1]]
original_prices = [prc_a[0], prc_b[0], prc_c[0], prc_d[0]]
new_prices = [prc_a[1], prc_b[1], prc_c[1], prc_d[1]]

"""
Cross Elasticities between pairs A,B and C,D

  | A | B | C | D 
A |   |   |   |
B |   |   |   | 
C |   |   |   | 
D |   |   |   |
"""

ceds = get_all_cross_elasticities(original_quantities=original_quantities,
                                  new_quantities=new_quantities,
                                  original_prices=original_prices,
                                  new_prices=new_prices)

assert ceds.shape == (len(skus), len(skus))
assert isclose(ceds[np.argwhere(skus == "A"), np.argwhere(skus == "A")], -41)
assert isclose(ceds[np.argwhere(skus == "B"), np.argwhere(skus == "A")], 13.66666666666666)
assert isclose(ceds[np.argwhere(skus == "D"), np.argwhere(skus == "C")], -0.4285714286)
assert isclose(ceds[np.argwhere(skus == "C"), np.argwhere(skus == "A")], 1)
assert isclose(ceds[np.argwhere(skus == "A"), np.argwhere(skus == "C")], 9)

Performance

Core elasticity function

Number of Products Time in Seconds
1,000 0.065512
10,000 0.200022
100,000 1.727269
1,000,000 26.730988

Project details


Download files

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

Source Distribution

retail-stats-0.0.2.post1.tar.gz (5.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

retail_stats-0.0.2.post1-py3-none-any.whl (17.9 kB view details)

Uploaded Python 3

File details

Details for the file retail-stats-0.0.2.post1.tar.gz.

File metadata

  • Download URL: retail-stats-0.0.2.post1.tar.gz
  • Upload date:
  • Size: 5.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/50.3.0 requests-toolbelt/0.9.1 tqdm/4.49.0 CPython/3.7.4

File hashes

Hashes for retail-stats-0.0.2.post1.tar.gz
Algorithm Hash digest
SHA256 28c0445bb15fe623ea4cefec1985c0acb7f5d4feb346374448ed509e1c0cfcae
MD5 339ebde3f3c47b27997dc7c0f20870fc
BLAKE2b-256 6d5fbba6588e14d41448b89b4a21a0002a2a4557164888611f3334862323bd88

See more details on using hashes here.

File details

Details for the file retail_stats-0.0.2.post1-py3-none-any.whl.

File metadata

  • Download URL: retail_stats-0.0.2.post1-py3-none-any.whl
  • Upload date:
  • Size: 17.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/50.3.0 requests-toolbelt/0.9.1 tqdm/4.49.0 CPython/3.7.4

File hashes

Hashes for retail_stats-0.0.2.post1-py3-none-any.whl
Algorithm Hash digest
SHA256 f1e6c3e9a42b6afb386ab15b854b441053d50c7a5302170839370ec5a342252c
MD5 31b7d0ba544afb091db3eae179140d52
BLAKE2b-256 4bd886dc38f1d77f39f268d1660e9ce3077ba6cd6b53cd50b5077f031567dce5

See more details on using hashes here.

Supported by

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