关于 pint-units
pint-units 是介绍 Python Pint 的技能,面向需要处理物理量的工程与科学计算。内容涵盖单位转换、量纲校验及带单位运算。
主要功能
- 01自动转换兼容单位
- 02检查量纲一致性
- 03执行带单位的算术运算
- 04与 NumPy 数组集成
- 05定义自定义单位
- 06处理温度及偏移单位
适用场景
- 01转换工程计算中的压力与流量
- 02验证速度、力等公式的量纲
- 03对 NumPy 数组进行带单位计算
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ soljourner/ claude-engineering-skills --skill pint-units安装后在 Claude Code 中输入/pint-units确认已加载。
附带文件examples.py
详细介绍
Pint Units 技能
概述
Pint 是一个用于处理带单位物理量的 Python 软件包。它提供:
- 自动单位换算
- 量纲分析和一致性检查
- 支持单位的算术运算
- 与 NumPy 数组集成
- 支持自定义单位定义
- 温度换算(包括偏移单位)
- 科学计数法和格式化
Pint 可消除单位换算错误,并确保工程计算中的量纲一致性,因此对于任何涉及物理量的技术工作都不可或缺。
安装
pip install pint
要与 NumPy 和 Pandas 集成:
pip install pint[numpy]
基本用法
创建物理量
Pint 中的物理量由一个大小(数值)和一个单位组成。
from pint import UnitRegistry
# Create unit registry (do this once per module)
ureg = UnitRegistry()
# Define quantities with units
distance = 100 * ureg.meter
time = 5 * ureg.second
pressure = 50 * ureg.psi
# Alternative syntax using string parsing
flow_rate = ureg('250 gallons/minute')
temperature = ureg('75 degF')
viscosity = ureg('1.5 centipoise')
# Access magnitude and units
print(f"Distance magnitude: {distance.magnitude}") # 100
print(f"Distance units: {distance.units}") # meter
单位换算
自动在兼容单位之间换算:
# Length conversions
distance = 100 * ureg.meter
print(distance.to('feet')) # 328.084 foot
print(distance.to('kilometer')) # 0.1 kilometer
# Pressure conversions
pressure = 100 * ureg.psi
print(pressure.to('bar')) # 6.895 bar
print(pressure.to('pascal')) # 689475.7 pascal
# Flow rate conversions
flow = 500 * ureg.gallons / ureg.minute
print(flow.to('liter/second')) # 31.546 liter/second
print(flow.to('m**3/hour')) # 113.562 meter**3/hour
# Temperature conversions (handles offset units)
temp = 75 * ureg.degF
print(temp.to('degC')) # 23.889 degree_Celsius
print(temp.to('kelvin')) # 297.039 kelvin
量纲分析
Pint 可确保计算中的量纲一致性:
# Velocity = Distance / Time
distance = 100 * ureg.meter
time = 5 * ureg.second
velocity = distance / time
print(velocity) # 20.0 meter/second
# Force = Mass × Acceleration
mass = 10 * ureg.kg
acceleration = 9.81 * ureg.meter / ureg.second**2
force = mass * acceleration
print(force) # 98.1 kilogram·meter/second²
print(force.to('newton')) # 98.1 newton
# Dimensional consistency check
try:
invalid = (100 * ureg.meter) + (50 * ureg.second) # ❌ ERROR
except Exception as e:
print(f"Error: Cannot add length and time")
# Correct operation
total_distance = (100 * ureg.meter) + (50 * ureg.feet) # ✓ OK
print(total_distance) # 115.24 meter
支持单位的计算
流体流量计算
# Calculate volumetric flow rate from velocity and area
velocity = 3.5 * ureg.meter / ureg.second
diameter = 150 * ureg.millimeter
area = 3.14159 * (diameter/2)**2
flow_rate = velocity * area
print(flow_rate.to('liter/second')) # 61.86 liter/second
print(flow_rate.to('gpm')) # 1638.1 gallon/minute
# Reynolds number calculation
density = 998 * ureg.kg / ureg.meter**3
viscosity = 1.0 * ureg.centipoise # Common unit in industry
Re = (density * velocity * diameter) / viscosity
print(Re.to_base_units()) # Dimensionless: 523170.0
泵功率计算
# Hydraulic power: P = ρ × g × Q × H
flow_rate = 100 * ureg.meter**3 / ureg.hour
head = 50 * ureg.meter
density = 1000 * ureg.kg / ureg.meter**3
gravity = 9.81 * ureg.meter / ureg.second**2
hydraulic_power = density * gravity * flow_rate * head
print(hydraulic_power.to('kilowatt')) # 13.625 kilowatt
print(hydraulic_power.to('horsepower')) # 18.27 horsepower
# With pump efficiency
efficiency = 0.75 * ureg.dimensionless
shaft_power = hydraulic_power / efficiency
print(shaft_power.to('kilowatt')) # 18.17 kilowatt
压降计算
# Darcy-Weisbach equation: ΔP = f × (L/D) × (ρV²/2)
friction_factor = 0.018 * ureg.dimensionless
length = 100 * ureg.meter
diameter = 0.15 * ureg.meter
velocity = 2.5 * ureg.meter / ureg.second
density = 1000 * ureg.kg / ureg.meter**3
pressure_drop = friction_factor * (length/diameter) * (density * velocity**2 / 2)
print(pressure_drop.to('pascal')) # 37500.0 pascal
print(pressure_drop.to('psi')) # 5.44 pound_force_per_square_inch
print(pressure_drop.to('bar')) # 0.375 bar
# Convert to head loss
head_loss = pressure_drop / (density * gravity)
print(head_loss.to('meter')) # 3.822 meter
print(head_loss.to('feet')) # 12.54 foot
处理数组
Pint 可与 NumPy 无缝集成,执行数组运算:
import numpy as np
from pint import UnitRegistry
ureg = UnitRegistry()
# Create array with units
flow_rates = np.array([50, 75, 100, 125, 150]) * ureg.gpm
heads = np.array([80, 75, 65, 50, 30]) * ureg.meter
# Array operations preserve units
powers = (flow_rates * heads * ureg.kg/ureg.meter**3 * 9.81*ureg.meter/ureg.second**2)
print(powers.to('kilowatt'))
# [2.48 3.72 4.95 6.19 7.43] kilowatt
# Statistical operations
mean_flow = np.mean(flow_rates)
std_flow = np.std(flow_rates)
print(f"Mean flow: {mean_flow.to('liter/minute'):.1f}")
print(f"Std dev: {std_flow.to('liter/minute'):.1f}")
# Unit-aware interpolation
target_head = 70 * ureg.meter
target_flow = np.interp(target_head.magnitude, heads[::-1].magnitude,
flow_rates[::-1].magnitude) * ureg.gpm
print(f"Flow at {target_head}: {target_flow.to('m**3/hour'):.1f}")
自定义单位定义
定义特定领域的单位:
# Add custom units to registry
ureg.define('barrel_oil = 42 * gallon = bbl')
ureg.define('standard_cubic_foot = foot**3 = scf')
ureg.define('darcy = centipoise * centimeter**2 / (second * atmosphere) = D')
# Use custom units
oil_volume = 1000 * ureg.barrel_oil
print(oil_volume.to('gallon')) # 42000.0 gallon
print(oil_volume.to('liter')) # 158987.3 liter
gas_flow = 5000 * ureg.standard_cubic_foot / ureg.day
print(gas_flow.to('m**3/hour')) # 5.90 meter**3/hour
permeability = 100 * ureg.darcy
print(permeability.to_base_units()) # Base SI units
单位系统的上下文管理器
轻松切换单位系统:
from pint import UnitRegistry
ureg = UnitRegistry()
length = 100 * ureg.meter
mass = 50 * ureg.kg
# Default SI units
print(f"Length: {length}") # 100 meter
print(f"Mass: {mass}") # 50 kilogram
# Use US customary units
with ureg.context('US'):
print(f"Length: {length.to('feet')}") # 328.084 foot
print(f"Mass: {mass.to('pound')}") # 110.231 pound
# Use imperial units
with ureg.context('imperial'):
print(f"Length: {length.to('yard')}") # 109.361 yard
温度换算
正确处理绝对温度和相对温度:
# Absolute temperatures
temp1 = 25 * ureg.degC
temp2 = temp1.to('degF')
print(temp2) # 77.0 degree_Fahrenheit
temp3 = 300 * ureg.kelvin
print(temp3.to('degC')) # 26.85 degree_Celsius
# Temperature differences (delta)
temp_rise = ureg.Quantity(20, ureg.delta_degC)
print(temp_rise.to(ureg.delta_degF)) # 36.0 delta_degree_Fahrenheit
# Heat transfer calculation
mass = 10 * ureg.kg
specific_heat = 4.18 * ureg.kJ / (ureg.kg * ureg.kelvin)
temp_change = 50 * ureg.delta_degC
heat = mass * specific_heat * temp_change
print(heat.to('kJ')) # 2090.0 kilojoule
print(heat.to('BTU')) # 1981.9 BTU
格式化和显示
控制物理量的显示方式:
pressure = 150000 * ureg.pascal
# Default format
print(pressure) # 150000 pascal
# Compact notation
print(f"{pressure:~}") # 150000 Pa
# Specific precision
print(f"{pressure:.2f}") # 150000.00 pascal
# Scientific notation
print(f"{pressure:~.2e}") # 1.50e+05 Pa
# Pretty format
print(f"{pressure:~P}") # 150000 Pa
# Custom format
print(f"{pressure.to('bar'):.3f~P}") # 1.500 bar
常见工程单位换算
压力
pressure = 100 * ureg.psi
# Common conversions
print(pressure.to('bar')) # 6.895 bar
print(pressure.to('kPa')) # 689.476 kilopascal
print(pressure.to('MPa')) # 0.689 megapascal
print(pressure.to('atm')) # 6.805 atmosphere
print(pressure.to('mmHg')) # 5171.5 millimeter_Hg
print(pressure.to('inch_H2O')) # 2767.7 inch_H2O
流量
flow = 100 * ureg.gpm # gallons per minute
# Common conversions
print(flow.to('liter/minute')) # 378.541 liter/minute
print(flow.to('m**3/hour')) # 22.712 meter**3/hour
print(flow.to('ft**3/second')) # 0.223 foot**3/second
print(flow.to('barrel_oil/day')) # 3428.57 barrel_oil/day (if defined)
黏度
# Dynamic viscosity
mu = 1.0 * ureg.centipoise
print(mu.to('pascal*second')) # 0.001 pascal·second
print(mu.to('lbf*second/ft**2')) # 2.089e-05 pound_force·second/foot²
# Kinematic viscosity
nu = 1.0 * ureg.centistokes
print(nu.to('m**2/second')) # 1e-06 meter²/second
print(nu.to('ft**2/second')) # 1.076e-05 foot²/second
能量和功率
energy = 100 * ureg.kWh
print(energy.to('MJ')) # 360.0 megajoule
print(energy.to('BTU')) # 341214.2 BTU
print(energy.to('therm')) # 3.412 therm
power = 50 * ureg.horsepower
print(power.to('kilowatt')) # 37.285 kilowatt
print(power.to('BTU/hour')) # 127259.0 BTU/hour
质量流量
mass_flow = 1000 * ureg.kg / ureg.hour
print(mass_flow.to('lb/minute')) # 36.74 pound/minute
print(mass_flow.to('ton/day')) # 0.024 metric_ton/day
print(mass_flow.to('g/second')) # 277.78 gram/second
最佳实践
- 仅创建一次 UnitRegistry:在模块级别定义
ureg = UnitRegistry(),不要在函数内部定义 - 使用基本单位存储:在数据库中使用一致的基本单位(SI)存储数值
- 验证输入单位:始终检查输入物理量是否具有预期的量纲
- 处理无量纲物理量:对于无单位比值,使用
ureg.dimensionless - 在边界处换算:仅在展示结果时换算为显示单位
- 检查兼容性:使用
quantity.check(dimension)验证量纲一致性 - 明确指定:使用明确的单位定义,不要依赖默认值
- 谨慎处理温度:对于温差,使用
delta_前缀;对于绝对温度则不使用
量纲一致性检查
def calculate_reynolds_number(velocity, diameter, density, viscosity):
"""
Calculate Reynolds number with automatic dimensional checking.
Re = ρVD/μ (dimensionless)
"""
# Pint automatically checks dimensions
Re = (density * velocity * diameter) / viscosity
# Verify result is dimensionless
assert Re.dimensionality == ureg.dimensionless.dimensionality
# Return magnitude (pure number)
return Re.to_base_units().magnitude
# Correct usage
rho = 1000 * ureg.kg / ureg.meter**3
V = 2.5 * ureg.meter / ureg.second
D = 0.15 * ureg.meter
mu = 1e-3 * ureg.pascal * ureg.second
Re = calculate_reynolds_number(V, D, rho, mu)
print(f"Reynolds number: {Re:.0f}") # 375000
# Incorrect usage will raise error
try:
Re_wrong = calculate_reynolds_number(V, D, rho, rho) # Wrong dimension
except Exception as e:
print("Error: Dimensional inconsistency detected")
与工程工作流集成
示例:泵性能曲线
import numpy as np
from pint import UnitRegistry
ureg = UnitRegistry()
def pump_curve(flow_rates, coefficients):
"""
Calculate pump head from flow rate using curve fit.
H = H0 - A*Q - B*Q²
Parameters
----------
flow_rates : Quantity array
Flow rates with units
coefficients : dict
'H0', 'A', 'B' with appropriate units
Returns
-------
heads : Quantity array
Pump heads with units
"""
H0 = coefficients['H0']
A = coefficients['A']
B = coefficients['B']
heads = H0 - A * flow_rates - B * flow_rates**2
return heads
# Define pump curve coefficients
coeffs = {
'H0': 80 * ureg.meter,
'A': 200 * ureg.meter / (ureg.meter**3/ureg.second),
'B': 3000 * ureg.meter / (ureg.meter**3/ureg.second)**2
}
# Calculate performance at different flow rates
Q = np.linspace(0, 0.1, 11) * ureg.meter**3 / ureg.second
H = pump_curve(Q, coeffs)
# Display in different units
print("Flow (GPM) Head (ft) Head (m)")
print("-" * 40)
for q, h in zip(Q, H):
print(f"{q.to('gpm'):8.0f~P} {h.to('feet'):8.1f~P} {h.to('meter'):7.1f~P}")
故障排除
问题:DimensionalityError
原因:尝试对单位不兼容的物理量进行相加或比较 解决方案:检查所有项是否具有相同量纲,或进行显式换算
问题:UndefinedUnitError
原因:使用注册表中未定义的单位
解决方案:使用 ureg.define() 定义自定义单位,或检查拼写
问题:偏移单位(温度)错误
原因:混用绝对温度单位和相对温度单位
解决方案:温差使用 delta_degC,绝对温度使用 degC
问题:计算中单位丢失
原因:在计算中过早使用 .magnitude
解决方案:在最终输出前,始终将物理量保留为 Pint 对象
速查卡
常用单位
| 数量 | 单位 |
|---|---|
| 长度 | 米、英尺、英寸、英里、千米 |
| 面积 | meter2、foot2、英亩、公顷 |
| 体积 | 升、加仑、桶(石油)、ft3、m3 |
| 质量 | 千克、磅、吨、吨(公制) |
| 时间 | 秒、分钟、小时、天 |
| 速度 | meter/second、ft/second、mph、kph |
| 流量(体积) | m3/hour、gpm、liter/minute、ft3/second |
| 流量(质量) | kg/second、lb/minute、ton/hour |
| 压力 | 帕斯卡、巴、psi、atm、mmHg |
| 力 | 牛顿、lbf、kgf |
| 功率 | 瓦、马力、BTU/hour |
| 能量 | 焦耳、kWh、BTU、卡路里 |
| 温度 | degC、degF、kelvin、rankine |
| 黏度(动力) | pascal*second、poise、centipoise |
| 黏度(运动) | m**2/second、stokes、centistokes |
快速换算
# Create quantity
Q = 100 * ureg.gpm
# Convert
Q.to('liter/minute') # To specific unit
Q.to_base_units() # To SI base units
Q.to_compact() # To compact SI (kilo, mega, etc)
# Check dimensionality
Q.dimensionality # [length]³/[time]
Q.check('[volume]/[time]') # Verify dimension
# Access components
Q.magnitude # Numeric value
Q.units # Unit object
参考资料
- 官方文档:https://pint.readthedocs.io/
- 源代码:https://github.com/hgrecco/pint
- 单位定义:https://github.com/hgrecco/pint/blob/master/pint/default_en.txt
- NIST《SI 指南》:https://www.nist.gov/pml/special-publication-811
延伸阅读
- NIST 特别出版物 811:《国际单位制(SI)使用指南》
- ISO 80000:量和单位
- 石油行业单位相关的 API 标准
- 工程计算相关的 ASME 标准
评论
支持 Markdown