Skip to main content

A comprehensive pandas extension for financial data cleaning, performance analysis, and valuation.

Project description

pd-money

License: MIT PyPI version Code style: black

A comprehensive pandas extension for financial data cleaning, performance analysis, and valuation.

Installation

pip install pd-money

Quick Start

import pandas as pd
import pd_money

df = pd.DataFrame({"Revenue": ["$1,000.00", "(500.00)", "-"]})
df["Revenue"] = df["Revenue"].money.clean()
# Result: [1000.0, -500.0, 0.0]

Features Guide

1. Cleaning & Formatting

Clean Safely convert "dirty" strings (currency symbols, parentheses for negatives, dashes for zero) into floats.

s = pd.Series(["$1,000.50", "(200.00)", "-", "10%"])

# Standard Clean
print(s.money.clean())
# 0    1000.5
# 1    -200.0
# 2       0.0
# 3      10.0
# dtype: float64

# Clean Percentages
print(s.money.clean(percent=True))
# 3    0.10

Format Convert numbers back into formatted currency strings, supporting accounting notation.

s = pd.Series([1000.5, -200.0, 0.0])

print(s.money.format(accounting=True))
# 0      $1,000.50
# 1      ($200.00)
# 2          $0.00
# dtype: string

2. Validation

Lint Scan your data for "Financial Data Smells" like mixed currencies, Excel errors, or precision issues.

s = pd.Series(["$100", "€50", "#DIV/0!"])
report = s.money.lint()

print(report)
# [
#   "[FAIL] 1 rows contain Excel error strings.",
#   "[WARN] Mixed currency symbols detected: $, €"
# ]

3. Conversion

FX Conversion Vectorized currency conversion using a rate table.

# Input Data
df = pd.DataFrame({
    "Date": pd.to_datetime(["2023-01-01", "2023-01-02"]),
    "Amount_EUR": [100.0, 200.0]
})

# Rates Table
rates = {
    pd.Timestamp("2023-01-01"): 1.05, 
    pd.Timestamp("2023-01-02"): 1.06
}

# Run
df["Amount_USD"] = df["Amount_EUR"].money.convert(
    to="USD", 
    rates=rates, 
    dates=df["Date"]
)

print(df["Amount_USD"])
# 0    105.0
# 1    212.0
# Name: Amount_USD, dtype: float64

Unit Scaling Scale values up or down (Thousands, Millions, Billions).

s = pd.Series([1500000.0])

# To "Millions" formatted string
print(s.money.to_unit("m"))
# 0    1.5M
# dtype: object

# From "Millions" to raw number
s2 = pd.Series(["1.5"])
print(s2.money.from_unit("m"))
# 0    1500000.0
# dtype: float64

4. Analysis & Risk

CAGR (Compound Annual Growth Rate) Calculate the smooth annual growth rate over a period.

# Time Series Input
df = pd.DataFrame({
    "Date": pd.to_datetime(["2020-01-01", "2022-01-01"]),
    "Price": [100.0, 121.0]
}).set_index("Date")

# Run (Auto-infers period from index)
print(df["Price"].money.cagr())
# 0.10  (10%)

Drawdown Calculate the decline from the historical peak.

s = pd.Series([100, 120, 60, 120])

print(s.money.drawdown())
# 0    0.0
# 1    0.0
# 2   -0.5  (Down 50% from peak of 120)
# 3    0.0
# dtype: float64

Volatility Calculate annualized volatility (default assumes daily data).

# Daily returns series
s = pd.Series([100, 101, 99, 100])
print(s.money.volatility())
# 0.158... (Annualized Std Dev)

Beta Calculate systematic risk relative to a benchmark.

asset = pd.Series([100, 102, 104]) # +2%, +1.96%
bench = pd.Series([100, 101, 102]) # +1%, +0.99%

print(asset.money.beta(benchmark=bench))
# 2.0

5. Valuation

XIRR (Internal Rate of Return) Calculate IRR for irregular cash flows. Requires a DatetimeIndex.

df = pd.DataFrame({
    "Date": pd.to_datetime(["2020-01-01", "2021-01-01"]),
    "Flow": [-1000.0, 1100.0]
}).set_index("Date")

print(df["Flow"].money.xirr())
# 0.10 (10%)

NPV (Net Present Value) Discount irregular cash flows to today's value.

print(df["Flow"].money.npv(rate=0.08))
# 18.51 (Positive NPV at 8% discount rate)

6. Allocation

Allocate Split amounts into components based on weights, handling rounding errors ("penny-perfect").

s = pd.Series([100.00]) # Split $100 into 3 equal parts

# Run
splits = s.money.allocate([1, 1, 1])

print(splits)
#        0      1      2
# 0  33.34  33.33  33.33
# (Sum is exactly 100.00)

7. Utilities

Fiscal Year Convert calendar dates to Fiscal Year strings.

dates = pd.Series(pd.to_datetime(["2023-10-15"]))

# US Government Fiscal Year (Starts Oct 1)
print(dates.money.fiscal_year(start_month=10))
# 0    FY2024 Q1
# dtype: string

Profile Generate a comprehensive financial summary stats report.

s = pd.Series([100, 200, -50, 0, None])
print(s.money.profile())

# count             4.0
# sum             250.0
# min             -50.0
# max             200.0
# zeros             1.0
# negatives         1.0
# nulls             1.0
# max_drawdown     -1.25
# cagr             None
# dtype: float64

Why pd-money?

Financial data is notoriously messy. Parentheses for negatives, mixed symbols, and rounding errors make standard pandas operations repetitive and fragile. pd-money provides a clean, vectorized accessor (.money) to handle these edge cases idiomatically.

Contributing

We welcome contributions!

  1. Fork the repository.
  2. Install in editable mode: pip install -e .
  3. Add your feature and a test.
  4. Submit a Pull Request.

License

MIT License. See LICENSE for details.

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

pd_money-0.1.2.tar.gz (16.2 kB view details)

Uploaded Source

Built Distribution

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

pd_money-0.1.2-py3-none-any.whl (17.8 kB view details)

Uploaded Python 3

File details

Details for the file pd_money-0.1.2.tar.gz.

File metadata

  • Download URL: pd_money-0.1.2.tar.gz
  • Upload date:
  • Size: 16.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for pd_money-0.1.2.tar.gz
Algorithm Hash digest
SHA256 93bbb227bdd50c9d88b12cf11e403e77b31ed958b16c0df4aa9e478a6356cd8c
MD5 1dd2000f2ad3f14121677609c01fd41f
BLAKE2b-256 dfaedb42854a79bb2a95c701dc3b166f893d37f4a5b608f7f0fcd5c9c37d6858

See more details on using hashes here.

File details

Details for the file pd_money-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: pd_money-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 17.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for pd_money-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 471ff61cf35ee5a23677b126c9485f2f7c9934a3ea3dc07aaceba5a93cb67981
MD5 236a6fa84c276ab0314a90e5eb5f5faa
BLAKE2b-256 57034617e4d988c23c545c10be2b007ad4103203051fbdaeffbad159842e8113

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