在Python 3.7.3和Pandas 0.25.0上获得此数据
import pandas as pd
test = {'data':['1/2 lorem ipsum','2/3 ipsum lorem 4/5','6/7 lorem ipsum',
'8.2/9 ipsum lorem 10.12/13']}
df = pd.DataFrame(test)
我想分别提取分子和分母,并且只考虑最后一个分数,所以只有一个是给定的,如果第二个是两个,则为第二个。不得超过两个,并且它们之间是一些文本。
我将其用于分母,在前划线后提取任何数字:
print(df.data.str.extract('(?:.*\/(\d+)){0}.*\/(\d+)')[1])
0 2
1 5
2 7
3 13
Name: 1, dtype: object
我无法使它适用于分子,可能是因为它们可能包含小数的复杂性。 我得到的最接近的是这种代码,使用的代码类似于上面的代码,加上对可能的小数的处理:
df.data.str.extract('(?:((?:\d+\.)?\d+)\/){0}(?:((?:\d+\.)?\d+)\/)')[1]
0 1
1 2
2 6
3 8.2
Name: 1, dtype: object
它正确地选择了小数点,但仅返回前几个分数的结果。预期的数字将是1,4,6,10.12
尝试了无数种代码变化后,我被卡住了,希望能找到错误。
答案 0 :(得分:3)
我建议使用以下正则表达式:
includes
只要不在同一个字符串中的其他分数后面,它将匹配一个分数。
说明:
def index
@schedule_dates = ScheduleDate.where(date: 1.week.ago..Float::INFINITY).includes(:orders)
end
答案 1 :(得分:1)
更多的熊猫样式代码,带有用于分数的简单正则表达式。
import pandas as pd
test = {'data':[
'1/2 lorem ipsum',
'2/3 ipsum lorem 4/5',
'6/7 lorem ipsum',
'8.2/9 ipsum lorem 10.12/13']}
df = pd.DataFrame(test)
fractions = df.data.str.extractall('(\d+\.?\d*)/(\d+)').groupby(level=0).tail(1)
numerators = fractions[0].tolist()
denominators = fractions[1].tolist()
print("Numerators:",numerators,"\nDenominators",denominators)
输出
Numerators: ['1', '4', '6', '10.12']
Denominators ['2', '5', '7', '13']
答案 2 :(得分:0)
您可以使用
>>> df.data.str.extract(r'(?:.*\D)?(?<!\d\.)(\d+(?:\.\d+)?)/(\d+(?:\.\d+)?)')
0 1
0 1 2
1 4 5
2 6 7
3 10.12 13
请参见regex demo。
详细信息
(?:.*\D)?
-可选的字符串,除了换行符以外,最多0个字符,最多至非数字... (?<!\d\.)
-不是紧跟数字和点... (\d+(?:\.\d+)?)
-捕获第1组:1个以上的数字以及.
和1个以上的数字的可选序列/
-一个/
(\d+(?:\.\d+)?)
-捕获第2组:1个以上的数字以及.
和1个以上的数字的可选序列。如果您需要分别获取字符串 中最后一个分数的值,请删除不必要的分组:
>>> df.data.str.extract(r'(?:.*\D)?(?<!\d\.)(\d+(?:\.\d+)?)/\d+(?:\.\d+)?')
0
0 1
1 4
2 6
3 10.12
>>> df.data.str.extract(r'(?:.*\D)?(?<!\d\.)\d+(?:\.\d+)?/(\d+(?:\.\d+)?)')
0
0 2
1 5
2 7
3 13