Neat formatting for numbers, dates, and strings using numpy.
Project description
pyneatR
Neat formatting for numbers, dates, timestamps, and strings using numpy.
Implementation inspired by the R package neatR.
Installation
pip install pyneatR
Neat Data for Presentation
Formatting dates
Often, we encounter dates in various formats and want an unambiguous representation. ndate formats dates into a readable mmm dd, yyyy format with the day of the week.
from pyneatR import ndate, nday
from datetime import date, timedelta
today = date.today()
# Assuming today is Nov 09, 2025 (Sun) for these examples
print(ndate(today - timedelta(days=3)))
# "Nov 06, 2025 (Thu)"
print(ndate(today))
# "Nov 09, 2025 (Sun)"
print(ndate(today + timedelta(days=4)))
# "Nov 13, 2025 (Thu)"
To just get the date without the day of week, set show_weekday=False:
print(ndate(today, show_weekday=False))
# "Nov 09, 2025"
For monthly data, abbreviating the date to mmm'yy is elegant:
print(ndate(today, show_weekday=False, show_month_year=True))
# "Nov'25"
To see the context of the date with respect to current date (within 1 week), use nday.
print(nday(today, show_relative_day=False))
# "Sun"
```python
print(nday(today, show_relative_day=True))
# "Today, Sun"
Formatting timestamp
Timestamps are feature-rich representations of date and time.
from pyneatR import ntimestamp
from datetime import datetime
now = datetime.now()
# Assuming now is Nov 09, 2025 12:07:48 PM
print(ntimestamp(now))
# "Nov 09, 2025 12H 07M 48S PM (Sun)"
To extract and format only the time:
print(ntimestamp(now, show_weekday=False, show_date=False, show_timezone=False))
# "12H 07M 48S PM"
Components of time can be toggled on or off:
print(ntimestamp(now, show_date=False, show_weekday=False,
show_hours=True, show_minutes=True, show_seconds=False,
show_timezone=False))
# "12H 07M PM"
Formatting number
nnumber formats numeric data in a readable way, automatically handling large numbers.
from pyneatR import nnumber
import numpy as np
x = np.array([10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000])
print(nnumber(x))
# ['10.0' '100.0' '1.0 K' '10.0 K' '100.0 K' '1.0 Mn' '10.0 Mn' '100.0 Mn' '1.0 Bn']
print(nnumber(x, digits=0))
# ['10' '100' '1 K' '10 K' '100 K' '1 Mn' '10 Mn' '100 Mn' '1 Bn']
nnumber can automatically determine the best single unit for all numbers using unit='auto':
x = np.array([1e6, 99e3, 76e3, 42e3, 12e3, 789, 53])
print(nnumber(x, unit='auto'))
# ['1,000 K' '99 K' '76 K' '42 K' '12 K' '0.8 K' '0.1 K']
You can specify the unit directly:
print(nnumber(123456789.123456, unit='Mn'))
# "123.5 Mn"
Default units are 'K', 'Mn', 'Bn', 'Tn'. Custom labels can be provided:
print(nnumber(123456789.123456, unit='M', unit_labels={'million': 'M'}))
# "123.5 M"
Prefixes and suffixes can be added:
print(nnumber(123456789.123456, unit='Mn', prefix='$ '))
# "$ 123.5 Mn"
To show the raw number with separators:
print(nnumber(123456789.123456, digits=2, unit='', thousand_separator=','))
# "123,456,789.12"
Formatting percentages
npercent formats percentages, handling both decimals (0.228) and values already multiplied by 100 (22.8).
from pyneatR import npercent
print(npercent(22.8, is_ratio=False))
# "+22.8%"
print(npercent(0.228, is_ratio=True))
# "+22.8%"
By default is_ratio=True. The plus sign can be toggled:
print(npercent(0.228, show_plus_sign=False))
# "22.8%"
For growth factors:
tesla_2017 = 20
tesla_2023 = 200
g = (tesla_2023 - tesla_2017) / tesla_2017
print(npercent(g, show_plus_sign=True, show_growth_factor=True))
# "+900.0% (9.0x Growth)"
Formatting string
nstring formats character vectors, removing special characters or changing case.
from pyneatR import nstring
s = ' All MOdels are wrong. some ARE useful!!! '
print(nstring(s, case='title', remove_specials=True))
# "All Models Are Wrong Some Are Useful"
To retain only English alphabets and numbers:
print(nstring(s, case='title', remove_specials=True, ascii_only=True))
# "All Models Are Wrong Some Are Useful"
Smart Formatting with f
The f function is a "smart" formatter that infers the input type and applies the most appropriate pyneatR formatting with standardized defaults.
from pyneatR import f
from datetime import date, datetime
# Infers Date
print(f(date(2026, 1, 1)))
# "Jan 01, 2026"
# Infers Timestamp (with IST and Weekday)
print(f(datetime(2025, 11, 9, 12, 7, 48)))
# "Nov 09, 2025 12H 07M 48S PM IST (Sun)"
# Infers Number (with scaling and separators)
print(f(1345000000000))
# "1.3 Tn"
# Infers Percent (with growth factor and bps)
print(f(9.0, format_type='percent'))
# "+900.0% (9x growth, 90K basis points)"
# Infers String (Title Case + Cleaning)
print(f("all Models are Wrong!!!"))
# "All Models Are Wrong"
You can explicitly set format_type if inference isn't what you want: day, date, ts, number, percent, string. All standard parameters can be passed via **kwargs.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyneatr-0.1.4.tar.gz.
File metadata
- Download URL: pyneatr-0.1.4.tar.gz
- Upload date:
- Size: 20.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
252825c792dfec755ca3a6ef49ca2da666632238f731fcc921d86c64b547a070
|
|
| MD5 |
1d0c44575418416e7bca8064318814d5
|
|
| BLAKE2b-256 |
f7d07a6eebe0122b2c98486069f72a2f3750e085f39bd30613574b5a774ddf9d
|
File details
Details for the file pyneatr-0.1.4-py3-none-any.whl.
File metadata
- Download URL: pyneatr-0.1.4-py3-none-any.whl
- Upload date:
- Size: 13.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e2a87ac1c3d341141c741caf1aec2c16805b882504659ac44333a6e23cc36df
|
|
| MD5 |
357a7d4987b6fd22fc8cd52ef1562888
|
|
| BLAKE2b-256 |
e6d32dcd02ef1ecfd579e4e33890a5b1004b1cc7d122c9a7d1083325fe8c18f6
|