python Python中的单位转换
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1025145/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Units conversion in Python
提问by Paul
SymPyis a great tool for doing units conversions in Python:
SymPy是在 Python 中进行单位转换的好工具:
>>> from sympy.physics import units
>>> 12. * units.inch / units.m
0.304800000000000
You can easily roll your own:
您可以轻松推出自己的:
>>> units.BTU = 1055.05585 * units.J
>>> units.BTU
1055.05585*m**2*kg/s**2
However, I cannot implement this into my application unless I can convert degrees C (absolute) to K to degrees F to degrees R, or any combo thereof.
但是,除非我可以将 C(绝对)度数转换为 K 度到 F 度数到 R 度数或其任何组合,否则我无法将其实现到我的应用程序中。
I thought maybe something like this would work:
我想也许这样的事情会奏效:
units.degC = <<somefunc of units.K>>
But clearly that is the wrong path to go down. Any suggestions for cleanly implementing "offset"-type units conversions in SymPy?
但很明显,这是一条错误的道路。在 SymPy 中干净地实现“偏移”类型单位转换的任何建议?
Note: I'm open to trying other units conversion modules, but don't know of any besides Unum, and found it to be cumbersome.
注意:我愿意尝试其他单位转换模块,但不知道除了Unum之外的任何模块,并且发现它很麻烦。
Edit: OK, it is now clear that what I want to do is first determine if the two quantities to be compared are in the same coordinate system. (like time units reference to different epochs or time zones or dB to straight amplitude), make the appropriate transformation, then make the conversion. Are there any general coordinate system management tools? That would be great.
编辑:好的,现在很清楚我想要做的是首先确定要比较的两个数量是否在同一坐标系中。(如时间单位参考不同时期或时区或dB到直线幅度),进行适当的转换,然后进行转换。有没有通用的坐标系管理工具?那很好啊。
I would make the assumption that °F and °C always refer to Δ°F Δ°C within an expression but refer to absolute when standing alone. I was just wondering if there was a way to make units.degF
a function and slap a decorator property()
on it to deal with those two conditions.
我会假设°F 和°C 在表达式中总是指Δ°F Δ°C,但在单独使用时指的是绝对值。我只是想知道是否有一种方法可以创建units.degF
一个函数并property()
在其上添加一个装饰器来处理这两种情况。
But for now, I'll set units.C == units.K
and try to make it very clear in the documentation to use functions convertCtoK(...)
and convertFtoR(...)
when dealing with absolute units. (Just kidding. No I won't.)
但是现在,我将units.C == units.K
在文档中设置并尝试在使用函数convertCtoK(...)
和convertFtoR(...)
处理绝对单位时非常清楚。(开个玩笑。不,我不会。)
采纳答案by Autoplectic
I personally like Quantitiesthanks to its NumPyintegration, however it only does relative temperatures, not absolute.
由于其NumPy集成,我个人喜欢Quantities,但它只处理相对温度,而不是绝对温度。
回答by Miles
The Unum documentation has a pretty good writeup on why this is hard:
Unum 文档对为什么这很难:
Unum is unable to handle reliably conversions between °Celsius and Kelvin. The issue is referred as the 'false origin problem' : the 0°Celsius is defined as 273.15 K. This is really a special and annoying case, since in general the value 0 is unaffected by unit conversion, e.g. 0 [m] = 0 [miles] = ... . Here, the conversion Kelvin/°Celsius is characterized by a factor 1 and an offset of 273.15 K. The offset is not feasible in the current version of Unum.
Moreover it will presumably never be integrated in a future version because there is also a conceptual problem : the offset should be applied if the quantity represents an absolute temperature, but it shouldn't if the quantity represents a difference of temperatures. For instance, a raise of temperature of 1° Celsius is equivalent to a raise of 1 K. It is impossible to guess what is in the user mind, whether it's an absolute or a relative temperature. The question of absolute vs relative quantities is unimportant for other units since the answer does not impact the conversion rule. Unum is unable to make the distinction between the two cases.
Unum 无法可靠地处理 °C 和 Kelvin 之间的转换。该问题被称为“假原点问题”:0°C 被定义为 273.15 K。这确实是一个特殊且令人讨厌的情况,因为通常值 0 不受单位转换的影响,例如 0 [m] = 0 [英里] = ... . 此处,转换开尔文/摄氏度的特征在于系数为 1,偏移量为 273.15 K。该偏移量在当前版本的 Unum 中不可行。
此外,它可能永远不会被集成到未来的版本中,因为还有一个概念问题:如果数量表示绝对温度,则应该应用偏移量,但如果数量表示温度差异,则不应该应用偏移量。例如,温度升高 1°C 相当于升高 1K。无法猜测用户心中的想法,无论是绝对温度还是相对温度。绝对数量与相对数量的问题对于其他单位并不重要,因为答案不会影响转换规则。Unum 无法区分这两种情况。
It's pretty easy to conceptually see the problems with trying to represent absolute temperature conversion symbolically. With any normal relative unit, (x unit) * 2 == (x * 2) unit
—unit math is commutative. With absolute temperatures, that breaks down—it's difficult to do anything more complex than straight temperature conversions with no other unit dimensions. You're probably best off keeping all calculations in Kelvin, and converting to and from other temperature units only at the entry and exit points of your code.
从概念上很容易看出试图用符号表示绝对温度转换的问题。对于任何正常的相对单位,(x unit) * 2 == (x * 2) unit
-unit 数学是可交换的。对于绝对温度,这会崩溃——很难做比没有其他单位维度的直接温度转换更复杂的事情。您最好将所有计算保持在开尔文中,并且仅在代码的入口和出口点与其他温度单位相互转换。
回答by jfs
Example, how it could work:
例如,它是如何工作的:
>>> T(0*F) + 10*C
T(265.37222222222221*K) # or T(47767/180*K)
>>> T(0*F + 10*C)
T(283.15*K)
>>> 0*F + T(10*C)
T(283.15*K)
>>> 0*F + 10*C
10*K
>>> T(0*F) + T(10*C)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'absolute_temperature' and \
'absolute_temperature'
>>> T(0*F) - T(10*C)
T(245.37222222222223*K) # or T(44167/180*K)
>>> 0*F - 10*C
-10*K
回答by kdavies4
The natupackage handles units of temperature. For instance, you can do this:
所述NATU包处理温度的单元。例如,您可以这样做:
>>> from natu.units import K, degC, degF
>>> T = 25*degC
>>> T/K
298.1500
>>> T/degF
77.0000
>>> 0*degC + 100*K
100.0 degC
Prefixes are supported too:
也支持前缀:
>>> from natu.units import mdegC
>>> 100*mdegC/K
273.2500
natualso handles nonlinear units such as the decibel, not just those with offsets like degree Celsiusand degree Fahrenheit.
natu还处理非线性单位,例如分贝,而不仅仅是那些具有摄氏度和华氏度等偏移量的单位。
Relating to the first example you gave, you can do this:
关于你给出的第一个例子,你可以这样做:
>>> from natu import units
>>> 12*units.inch/units.m
0.3048
BTUis already built in. You can change its display unit to m**2*kg/s**2, but by default natusimplifies the unit to J:
BTU已经内置。您可以将其显示单位更改为 m**2*kg/s**2,但默认情况下natu 会将单位简化为 J:
>>> from natu.units import BTU
>>> BTU.display = 'm2*kg/s2'
>>> 1*BTU
1055.05585262 J