Python 中的单位转换

发布于 2024-07-25 13:35:40 字数 1142 浏览 7 评论 0原文

SymPy 是一个在 Python 中进行单位转换的好工具:

>>> from sympy.physics import units
>>> 12. * units.inch / units.m
0.304800000000000

您可以轻松地推出自己的:

>>> units.BTU = 1055.05585 * units.J
>>> units.BTU
1055.05585*m**2*kg/s**2

但是,我无法将其实现到我的应用程序中,除非我可以将 C 度(绝对)转换为 K 度、F 度到 R 度,或其任何组合。

我想也许这样的事情会起作用:

units.degC = <<somefunc of units.K>>

但显然这是错误的道路。 对于在 SymPy 中干净地实现“偏移”类型单位转换有什么建议吗?

注意:我愿意尝试其他单位转换模块,但除了 Unum< /a>,发现很麻烦。

编辑:好的,现在很清楚我想做的是首先确定要比较的两个量是否在同一坐标系中。 (例如时间单位参考不同的纪元或时区或 dB 到直线幅度),进行适当的转换,然后进行转换。 有没有通用的坐标系管理工具? 那太好了。

我会假设 °F 和 °C 在表达式中始终指 Δ°F Δ°C,但单独使用时指绝对值。 我只是想知道是否有一种方法可以使 units.degF 成为一个函数,并在其上添加一个装饰器 property() 来处理这两个条件。

但现在,我将设置 units.C ==units.K 并尝试在文档中明确说明如何使用函数 convertCtoK(...)convertFtoR(...) 处理绝对单位时。 (开玩笑。不,我不会。)

SymPy is a great tool for doing units conversions in 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.

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?

Note: I'm open to trying other units conversion modules, but don't know of any besides Unum, and found it to be cumbersome.

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.

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.

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.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

假装爱人 2024-08-01 13:35:40

Unum 文档有一篇很好的文章解释了为什么这很难:

Unum 无法可靠地处理摄氏度和开尔文之间的转换。 该问题被称为“错误原点问题”:0°C 被定义为 273.15 K。这确实是一个特殊且令人烦恼的情况,因为通常值 0 不受单位转换的影响,例如 0 [m] = 0 [英里] = ... . 此处,开尔文/°C 转换的特征是因子 1 和偏移量 273.15 K。该偏移量在当前版本的 Unum 中不可行。

此外,它可能永远不会集成到未来的版本中,因为还存在一个概念问题:如果数量代表绝对温度,则应应用偏移量,但如果数量代表温度差,则不应应用偏移量。 例如,温度升高 1°C 相当于升高 1K。无论是绝对温度还是相对温度,都无法猜测用户的想法。 绝对量与相对量的问题对于其他单位来说并不重要,因为答案不会影响转换规则。 Unum 无法区分这两种情况。

从概念上很容易看出尝试用符号表示绝对温度转换的问题。 对于任何正常的相对单位,(xunit) * 2 == (x * 2)unit——单位数学是可交换的。 对于绝对温度,这种情况就不成立了——很难做比没有其他单位量纲的直接温度转换更复杂的事情。 您可能最好将所有计算保留为开尔文,并且仅在代码的入口和出口点与其他温度单位进行相互转换。

The Unum documentation has a pretty good writeup on why this is hard:

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.

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.

烦人精 2024-08-01 13:35:40

我个人喜欢 Quantities,因为它的 NumPy 集成,但是它只处理相对温度,而不是绝对温度。

I personally like Quantities thanks to its NumPy integration, however it only does relative temperatures, not absolute.

岁月静好 2024-08-01 13:35:40

例如,它是如何工作的:

>>> 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

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
待天淡蓝洁白时 2024-08-01 13:35:40

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

也支持前缀:

>>> from natu.units import mdegC
>>> 100*mdegC/K
273.2500

natu 还可以处理非线性单位,例如 < a href="http://en.wikipedia.org/wiki/Decibel" rel="nofollow">分贝,不仅仅是那些带有偏移量的 摄氏度华氏度

关于您给出的第一个示例,您可以这样做:

>>> from natu import units
>>> 12*units.inch/units.m
0.3048

BTU 已经内置。您可以将其显示单位更改为 m**2*kg/s**2,但默认情况下 natu 简化单位为J:

>>> from natu.units import BTU
>>> BTU.display = 'm2*kg/s2'
>>> 1*BTU
1055.05585262 J

The natu package handles units of temperature. For instance, you can do this:

>>> 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

natu also handles nonlinear units such as the decibel, not just those with offsets like degree Celsius and degree Fahrenheit.

Relating to the first example you gave, you can do this:

>>> from natu import units
>>> 12*units.inch/units.m
0.3048

BTU is already built in. You can change its display unit to m**2*kg/s**2, but by default natu simplifies the unit to J:

>>> from natu.units import BTU
>>> BTU.display = 'm2*kg/s2'
>>> 1*BTU
1055.05585262 J
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文