数据集中,我有一个像这样的特征(称为Size
(:
import pandas as pd
dit={"Size" : ["0","0","5mm","12-15","3-10"] }
dt = pd.DataFrame(data=dit)
此功能指定一个范围(最小值和最大值(或特定数字的大小。
现在,我希望将值替换为每个范围的最大值。
因此,在我的示例中,输出应该是
dit={"Size" : ["0","0","5mm","15mm","10mm"] }
这是我尝试过的:
import re
dt = re.split("-",dt.loc[:,"Size"])
但是,它抱怨:
TypeError: expected string or bytes-like object
这是有道理的,因为dt.loc[:," Size (in mm)"]
的类型是:
pandas.core.series.Series
我的问题是,我怎样才能简单地更新此列而不循环?
import pandas as pd
import re
dit={"Size" : ["0","0","5mm","12-15","3-10"] }
dt = pd.DataFrame(data=dit)
rx = r'(d+)(?:mm)?-(d+)(?:mm)?'
dt['Size']=dt['Size'].apply(lambda x: re.sub(rx, lambda z: str(max(int(z.group(1)), int(z.group(2)))) + "mm", x))
输出:
>>> dt
Size
0 0
1 0
2 5mm
3 15mm
4 10mm
正则表达式匹配
-
(d+)
- 第 1 组:一个或多个数字 -
(?:mm)?
- 可选的mm
字符序列 -
-
- 连字符 -
(d+)
- 第 2 组:一个或多个数字 -
(?:mm)?
- - 可选的mm
字符序列。
str(max(int(z.group(1)), int(z.group(2)))) + "mm"
将数字的最大值保留在两组中,并在末尾附加mm
。
这个表达式可能会返回所需的输出,我假设mm
不需要:
import pandas as pd
dit={"Size" : ["0","0","5mm","12-15mm","3mm-10mm"] }
dt = pd.DataFrame(data=dit)
dt['max_size']=dt["Size"].str.replace(r"^.*?(d+)D*$",r"1")
print(dt)
输出
Size max_size
0 0 0
1 0 0
2 5mm 5
3 12-15mm 15
4 3mm-10mm 10
使用简单的掩码和Series.apply
功能:
In [172]: m = df['Size'].str.contains('-?d+mm$')
In [173]: df.loc[m, 'Size'] = df.loc[m, 'Size'].apply(lambda x: x.split('-')[-1])
In [174]: df
Out[174]:
Size
0 0
1 0
2 5mm
3 15mm
4 10mm
'-?d+mm$'
模式详细信息:
-
-?
- 匹配可选的-
字符 -
d+mm$
- 匹配字符串末尾的一个或多个数字d
后跟mm
后缀
$
我们可以使用这个简单的正则表达式来替换 -
之前的所有内容:
import pandas as pd
dit={"Size" : ["0","0","5mm","12-15mm","3mm-10mm"] }
dt = pd.DataFrame(data=dit)
dt["max_size"] = dt["Size"].str.replace(".*-","")
dt
Size max_size
0 0 0
1 0 0
2 5mm 5mm
3 12-15mm 15mm
4 3mm-10mm 10mm
如果最后不需要mm
,则:
dt["max_size"] = dt["Size"].str.replace(r".*-|mm$", "")
dt
Size max_size
0 0 0
1 0 0
2 5mm 5
3 12-15mm 15
4 3mm-10mm 10