Python 中的盎司换算为磅

Ounces to Pounds in Python

我有一列权重(实际上有 5k 个权重),一小批看起来像这样:

weight
15.00 oz
19.00 oz
2 lb 15.00 oz 
1 lb 19.00 oz

我想做的是将整个重量转换为磅,像这样:

weight
0.9375 lb
1.1875 lb
2.9375 lb
2.1875 lb

我应该怎么做才能实现这一目标? 到目前为止我尝试过的是:

df[['lbs','oz']] = df.Weight.str.split("lb",expand=True)

但这不起作用,对于没有 'lb' 单位的行,代码不起作用。 看起来像这样:

pounds    ounces
 15.00    oz
 19.00    oz
 2lb      15.00oz
 1lb      19.00oz
weights = [15, 19] #different weights here

for i in weights:
    weight = i / 16
    print(weight)

Try this, it should be working and it's a far simpler was of doing it that what you showed. Hope it works for you!

这可行,但几乎肯定有更简洁的 'more pandas' 方法...这应该足够快以处理 5,000 个值。

进口:

import pandas as pd

测试数据设置(包括.后带oz值的数据):

df = pd.DataFrame(["15.00 oz",
                   "19.00 oz",
                   "2 lb 15.00 oz",
                   "1 lb 19.00 oz",
                   "1 lb 12.80 oz",
                   "1 lb",
                   "nothing"],
                   columns=["weight"])

产生:

          weight
0       15.00 oz
1       19.00 oz
2  2 lb 15.00 oz
3  1 lb 19.00 oz
4  1 lb 12.80 oz
5           1 lb
6        nothing

定义一个函数,将单个 lb/oz 值映射到单个 lb 值。这需要一个元组数组,它​​可能是空的,例如: [(,'15.00')][][('1', '12.80')] (匹配中的 'numbers' 仍然是类型 str 此时):

def lbsFromMatchedNumbers(matchData):
    if len(matchData) == 0:
        return None
    (lbs, oz) = matchData[0]
    lbs = float(lbs or 0)
    oz = float(oz or 0)
    ounces_in_pound = 16.0
    return lbs + (oz / ounces_in_pound)

找到'weight'行的所有项,然后用函数处理,赋值给新的'lb'列:

matchPattern = "^(?:(\d+) lb ?)?(?:(\d+(?:.\d+)?) oz)?$"
df["lb"] = df["weight"].str.findall(matchPattern).apply(lbsFromMatchedNumbers)

产生:

          weight      lb
0       15.00 oz  0.9375
1       19.00 oz  1.1875
2  2 lb 15.00 oz  2.9375
3  1 lb 19.00 oz  2.1875
4  1 lb 12.80 oz  1.8000
5           1 lb  1.0000
6        nothing     NaN

注意:如果只有 lb 或 oz 数字,此方法有效,如我使用的示例数据中的额外行所示。如果两者都没有,它会产生 NaN.


正则表达式部分的解释

我们使用正则表达式 ('regular expression') 来匹配使用此模式的 'weight' 文本内容的部分: "^(?:(\d+) lb ?)?(?:(\d+(?:.\d+)?) oz)?$"

使用正则表达式语法

  • \d 查找单个 0-9 值
  • \d+ 查找一个或多个 0-9 值(例如,1 或 435245)
  • ?(一个,然后一个?)寻找一个 space,或者什么都不找(? 使其成为可选的)
  • (hello)? 寻找 'hello',但如果找不到则继续(由于 ?
  • 括号将项目组合在一起
  • 括号后跟 ?:(?:like this),将项目组合在一起,但不要将其保存为 'matched groups' 之一。在我们的例子中,只有两个数字被返回,当它们匹配时(因为它们被括在普通括号中)

我们的特定示例正则表达式

把它们放在一起,这个正则表达式基本上说:

  • 从字符串的最开始(标记为^
  • 这部分是可选的:
    • 寻找 1 个或多个 0-9 数字 - 如果找到它,它就是 'group 1'
    • 然后一个space
    • 然后是正文'lb'
    • 然后(可选)一个 space
  • 后跟(也是可选的):
    • 这整个部分是'group 2':
      • 1 个或多个 0-9 位数字
      • 这个位是可选的:
        • a .,后跟 1 个或多个 0-9 数字
    • 然后一个space
    • 然后是正文'oz'
    • 然后是字符串的结尾(用$标记)