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'
- 然后是字符串的结尾(用
$
标记)
我有一列权重(实际上有 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 数字
- a
- 然后一个space
- 然后是正文'oz'
- 然后是字符串的结尾(用
$
标记)
- 这整个部分是'group 2':