簡體   English   中英

單位換算 Python

[英]Unit Conversion in Python

我正在做一個項目,讓用戶可以隨着時間的推移跟蹤不同的數據類型。 基本思想的一部分是用戶應該能夠使用他們需要的任何單位輸入數據。 我一直在看這兩個單位:

http://pypi.python.org/pypi/units/

和數量:

http://pypi.python.org/pypi/quantities/

但是我不確定 go 的最佳方式。據我所知,數量更復雜,但包括更好的初始單位列表。

我贊賞在科學計算應用程序中使用顯式單位。 使用顯式單位類似於刷牙。 它預先增加了一些乏味,但從長遠來看,您獲得的類型安全可以節省很多麻煩。 比如說,沒有將價值 1.25 億美元的軌道飛行器撞向行星

您可能還應該查看另外兩個 python 單位/數量包:

單數

科學.物理.物理量

我曾經調查過 Scientific.Physics.PhysicalQuantity。 它不能完全滿足我的需求,但可能滿足您的需求。 很難從您的簡短描述中判斷您需要哪些功能。

我最終編寫了我自己的用於單位轉換和維度分析的 python 包,但它尚未正確打包以供發布。 我們在用於 GPU 加速分子力學的 OpenMM 系統的 Python 綁定中使用我的單位系統。 您可以在以下位置瀏覽我的 python 單元代碼的 svn 存儲庫:

SimTK python 單元

最終我打算將它打包分發。 如果你覺得有趣,請告訴我。 這可能會促使我盡快打包。 我在設計 SimTK python 單位系統時尋找的功能包括以下內容:

  1. 單位不一定在內部以 SI 單位存儲。 這對我來說非常重要,因為對我們來說一個重要的應用領域是分子尺度。 在內部使用 SI 單位會導致常用分子力計算中的指數溢出。 在內部,所有單位系統在 SimTK 中都是同等基礎的。
  2. 我想要與 C++ 中的Boost.Units系統類似的功能和靈活性。 既因為我熟悉那個系統,也因為它是在一大群傑出工程師的監督下設計的。 Boost.Units 是一個精心制作的第二代維度分析系統。 因此,我可能會爭辯說 SimTK 單位系統是第三代系統 :)。 請注意,雖然 Boost.Units 是一個沒有運行時成本的“零開銷”系統,但所有 python 數量實現,包括 SimTK 單元,可能都需要運行時成本。
  3. 我想要與 numpy 數組兼容的維度數量,但不一定需要 python numpy 包。 換句話說,Quantities 可以基於 numpy 數組或內置的 Python 類型。

哪些功能對您很重要?

品脫最近進入了這個領域。 有人願意分享他們的經驗嗎? 看起來挺好的。 僅供參考:看起來Pint 將在不久的將來與 Uncertainties 整合

yt-project 中還有另一個名為unyt 的包。 unyt 的作者承認 Pint 和 astropy.units 的存在。 支持與這些其他包之間的轉換。

unyt 的賣點是速度 它比其他兩個更快。 本文在多個基准測試中對單元包進行了比較。

對於任何痴迷於性能的人來說,這些基准測試都令人失望。 :-( 使用這些單位系統中的任何一個進行計算的速度減慢很大。對於具有 1000 個條目的數組,減慢系數為 6-10 (對於較小的數組更糟)。

免責聲明:我不隸屬於 unyt,我只是想分享我對單位系統的了解。

請注意, quantities對溫度的支持非常差:

>>> (100 * pq.degC).rescale(pq.degF)
array(179.99999999999997) * degF
>>> (0 * pq.degC).rescale(pq.degF)
array(0.0) * degF

0 攝氏度不是 0 華氏度。 他們的框架不支持任何類型的轉換,而不僅僅是乘以一個因子。

看起來另一個包也用於這樣做,由 web2py 成名的 Massimo DiPierro 編寫,稱為Buckingham

另外值得注意的是, Brian已經有一段時間了。

我很驚訝還沒有人提到 SymPy。 SymPy是一個成熟且維護良好的 Python 符號數學庫,也是NumFOCUS 贊助的項目。

它有一個物理模塊,其中包含許多用於“解決物理問題”的有用類和函數。 與您最相關的是,它有一個Unit子模塊,其中包含您需要的一切,我認為; 只需閱讀優秀的文檔。

您可能想查看一個名為natu的新包。 它解決了@ChristopherBruns 列出的三個問題。 它在PyPI 中可用。

我是該軟件包的作者,如果您有任何意見或建議,我將不勝感激。

我認為你應該使用數量,因為數量有一些與之相關的單位。

例如,壓力將是一個可以輸入並轉換為不同單位(Pa、psi、atm 等)的數量。 可能您可以為您的應用程序創建新的數量細節。

思想提單位包,它是Astropy包的一部分。

它維護良好,易於使用,並具有所有基本單元(以及與天體物理學相關的單元)。 它提供了單位和數量的工具。 還有一個物理常數模塊。

我想指出一個用於處理單位的單獨庫:Barril

https:\/\/github.com\/ESSS\/barril<\/a>

文檔位於: https<\/a> :\/\/barril.readthedocs.io\/en\/latest\/

雖然它確實支持從計算中創建“隨機”單位(例如 Pint、unum 等),但它更適合擁有一個單位數據庫(該庫默認具有該數據庫 - 請參閱: https:\/\/barril.readthedocs .io\/en\/latest\/units.html<\/a>和實現: https:\/\/github.com\/ESSS\/barril\/blob\/master\/src\/barril\/units\/posc.py<\/a> )然后您可以根據相關單位。

它支持的在這方面有很大不同的一件事是處理“無量綱”的單位轉換 - 例如 m3\/m3 (即: volume per volume<\/code> ),然后轉換為cm3\/m3<\/code>並保持尺寸。

即:品脫:

>>> import pint
>>> ureg = pint.UnitRegistry()
>>> m = ureg.meter
>>> v = 1 \* (m\*3)/(m\*3)
>>> v
<Quantity(1.0, 'dimensionless')>

我發現單位包比想要的要多。 不需要太多代碼就可以開始構建自己的函數,這些函數引用了極少數的基本數字。 此外,它會強制您進行尺寸分析以防止錯誤。

def FtoC(Tf):
    return (Tf-32)*5/9
def CtoF(Tc):
    return 9*Tc/5+32
def CtoK(Tc):
    return Tc+273.15
def INCHtoCM(Inch):
    return 2.54 * Inch
def CMtoINCH(cm):
    return cm / INCHtoCM(1)
def INCHtoMETER(inch):
    return .01*INCHtoCM(inch)
def FOOTtoMETER(foot):
    return INCHtoMETER(12*foot)
def METERtoINCH(Meter):
    return CMtoINCH(100 * Meter)
def METERtoFOOT(Meter):
    return METERtoINCH(Meter)/12
def M3toINCH3(M3):
    return (METERtoINCH(M3))**3
def INCH3toGALLON(Inch3):
    return Inch3 / 231
def M3toGALLON(M3):
    return INCH3toGALLON(M3toINCH3(M3))
def KG_M3toLB_GALLON(KGperM3):
    return KGtoLBM(KGperM3) / M3toGALLON(1)
def BARtoPASCAL(bar):
    return 100000 * bar
def KGtoLBM(kilogram):
    return kilogram * 2.20462262185
def LBMtoKG(lbm):
    return lbm/KGtoLBM(1)
def NEWTONtoLBF(newton):
    return newton * KGtoLBM(1) * METERtoFOOT(1) / STANDARD_GRAVITY_IMPERIAL()
def LBFtoNEWTON(lbf):
    return lbf * STANDARD_GRAVITY_IMPERIAL() * LBMtoKG(1) * FOOTtoMETER(1)
def STANDARD_GRAVITY_IMPERIAL():
    return 32.174049
def STANDARD_GRAVITY_SI():
    return 9.80665
def PASCALtoPSI(pascal):
    return pascal * NEWTONtoLBF(1) / METERtoINCH(1)**2
def PSItoPASCAL(psi):
    return psi * LBFtoNEWTON(1) / INCHtoMETER(1)**2

另一個要提到的 package 是Axiompy

安裝: pip install axiompy

from axiompy import Units
units = Units()
print(units.unit_convert(3 * units.metre, units.foot))
>>> <Value (9.84251968503937 <Unit (foot)>)>

我首選的 package 是QuantiPhy 它采用與大多數其他軟件包不同的方法。 對於 QuantiPhy,單位只是字符串,package 主要用於讀取或寫入數量。 因此,將其合並到您的軟件中要容易得多。 QuantiPhy 在創建數量和將它們呈現為字符串時都支持單位和比例因子轉換。 下面是一個讀取並寫入時間和溫度表的示例,在輸入時從分鍾/°F 轉換為秒/K,並在輸出時返回原始單位:

>>> from quanitphy import Quantity

>>> rawdata = '0 450, 10 400, 20 360'
>>> data = []
>>> for pair in rawdata.split(','):
...     time, temp = pair.split()
...     time = Quantity(time, 'min', scale='s')
...     temp = Quantity(temp, '°F', scale='K')
...     data += [(time, temp)]

>>> for time, temp in data:
...     print(f'{time:9q} {temp:9q}')
      0 s  505.37 K
    600 s  477.59 K
   1.2 ks  455.37 K

>>> for time, temp in data:
...     print(f"{time:<7smin} {temp:s°F}")
0 min   450 °F
10 min  400 °F
20 min  360 °F

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM