Python 将十进制数字转换成罗马数字
HSP_OLD是一个数据帧,tryl是HSP_OLD的一列,下面是tryl中的一些值示例: SAF/HSP:辅助诊断E代码1 SAF/HSP:辅助诊断E代码11Python 将十进制数字转换成罗马数字,python,regex,pandas,dictionary,replace,Python,Regex,Pandas,Dictionary,Replace,HSP_OLD是一个数据帧,tryl是HSP_OLD的一列,下面是tryl中的一些值示例: SAF/HSP:辅助诊断E代码1 SAF/HSP:辅助诊断E代码11 我使用字典来替换,它适用于1-10,但对于11,它将变为II,对于12,它将变为III。您需要保持项目的顺序,并开始使用最长的子字符串进行搜索 您可以在这里使用OrderDict。要初始化它,请使用元组列表。初始化时,您可以在此处将其反转,但也可以稍后再进行 d_hsp={"1":"I","2":"II","3":"III","4":"
我使用字典来替换,它适用于1-10,但对于11,它将变为II,对于12,它将变为III。您需要保持项目的顺序,并开始使用最长的子字符串进行搜索 您可以在这里使用OrderDict。要初始化它,请使用元组列表。初始化时,您可以在此处将其反转,但也可以稍后再进行
d_hsp={"1":"I","2":"II","3":"III","4":"IV","5":"V","6":"VI","7":"VII","8":"VIII",
"9":"IX","10":"X","11":"XI","12":"XII","13":"XIII","14":"XIV","15":"XV",
"16":"XVI","17":"XVII","18":"XVIII","19":"XIX","20":"XX","21":"XXI",
"22":"XXII","23":"XXIII","24":"XXIV","25":"XXV"}
HSP_OLD['tryl'] = HSP_OLD['tryl'].replace(d_hsp, regex=True)
您需要保持项目的顺序,并使用最长的子字符串开始搜索 您可以在这里使用OrderDict。要初始化它,请使用元组列表。初始化时,您可以在此处将其反转,但也可以稍后再进行
d_hsp={"1":"I","2":"II","3":"III","4":"IV","5":"V","6":"VI","7":"VII","8":"VIII",
"9":"IX","10":"X","11":"XI","12":"XII","13":"XIII","14":"XIV","15":"XV",
"16":"XVI","17":"XVII","18":"XVIII","19":"XIX","20":"XX","21":"XXI",
"22":"XXII","23":"XXIII","24":"XXIV","25":"XXV"}
HSP_OLD['tryl'] = HSP_OLD['tryl'].replace(d_hsp, regex=True)
很抱歉,我没有注意到您不仅在更新字段,而且实际上还想在末尾替换一个数字,但即使是这样,将数字正确地转换为罗马数字也比映射每一个可能出现的情况要好得多。如果数字大于25?,代码会发生什么情况?。所以,这里有一种方法:
import collections
import pandas as pd
# My test data
HSP_OLD = pd.DataFrame({'tryl':['1. Text', '11. New Text', '25. More here']})
d_hsp_lst=[("1","I"),("2","II"),("3","III"),("4","IV"),("5","V"),("6","VI"),("7","VII"),("8","VIII"), ("9","IX"),("10","X"),("11","XI"),("12","XII"),("13","XIII"),("14","XIV"),("15","XV"), ("16","XVI"),("17","XVII"),("18","XVIII"),("19","XIX"),("20","XX"),("21","XXI"), ("22","XXII"),("23","XXIII"),("24","XXIV"),("25","XXV")]
d_hsp = collections.OrderedDict(d_hsp_lst) # Creating the OrderedDict
d_hsp = collections.OrderedDict(reversed(d_hsp.items())) # Here, reversing
>>> HSP_OLD['tryl'] = HSP_OLD['tryl'].replace(d_hsp, regex=True)
>>> HSP_OLD
tryl
0 I. Text
1 XI. New Text
2 XXV. More here
现在,如果我们将您的数据框创建为:
ROMAN_MAP = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'), (100, 'C'), (90, 'XC'),
(50, 'L'), (40, 'XL'), (10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]
def romanize(data):
if not data or not isinstance(data, str): # we know how to work with strings only
return data
data = data.rstrip() # remove potential extra whitespace at the end
space_pos = data.rfind(" ") # find the last space before the number
if space_pos != -1:
try:
number = int(data[space_pos + 1:]) # get the number at the end
roman_number = ""
for i, r in ROMAN_MAP: # loop-reduce substitution based on the ROMAN_MAP
while number >= i:
roman_number += r
number -= i
return data[:space_pos + 1] + roman_number # put everything back together
except (TypeError, ValueError):
pass # couldn't extract a number
return data
我们无法轻松地将我们的函数应用于整个列:
HSP_OLD = pd.DataFrame({"tryl": ["SAF/HSP: Secondary diagnosis E code 1",
None,
"SAF/HSP: Secondary diagnosis E code 11",
"Something else without a number at the end"]})
其结果是:
HSP_OLD['tryl'] = HSP_OLD['tryl'].apply(romanize)
当然,您可以根据需要调整romanize函数,以搜索字符串中的任何数字并将其转换为罗马数字-这只是一个如何快速查找字符串末尾数字的示例。对不起,我没有注意到您不仅要更新字段,而且实际上要替换字符串末尾的数字,但即使是这样,正确地将数字转换为罗马数字也比映射每一个可能出现的数字要好得多。如果有一个大于25?的数字,代码会发生什么?。所以,这里有一种方法:
import collections
import pandas as pd
# My test data
HSP_OLD = pd.DataFrame({'tryl':['1. Text', '11. New Text', '25. More here']})
d_hsp_lst=[("1","I"),("2","II"),("3","III"),("4","IV"),("5","V"),("6","VI"),("7","VII"),("8","VIII"), ("9","IX"),("10","X"),("11","XI"),("12","XII"),("13","XIII"),("14","XIV"),("15","XV"), ("16","XVI"),("17","XVII"),("18","XVIII"),("19","XIX"),("20","XX"),("21","XXI"), ("22","XXII"),("23","XXIII"),("24","XXIV"),("25","XXV")]
d_hsp = collections.OrderedDict(d_hsp_lst) # Creating the OrderedDict
d_hsp = collections.OrderedDict(reversed(d_hsp.items())) # Here, reversing
>>> HSP_OLD['tryl'] = HSP_OLD['tryl'].replace(d_hsp, regex=True)
>>> HSP_OLD
tryl
0 I. Text
1 XI. New Text
2 XXV. More here
现在,如果我们将您的数据框创建为:
ROMAN_MAP = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'), (100, 'C'), (90, 'XC'),
(50, 'L'), (40, 'XL'), (10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]
def romanize(data):
if not data or not isinstance(data, str): # we know how to work with strings only
return data
data = data.rstrip() # remove potential extra whitespace at the end
space_pos = data.rfind(" ") # find the last space before the number
if space_pos != -1:
try:
number = int(data[space_pos + 1:]) # get the number at the end
roman_number = ""
for i, r in ROMAN_MAP: # loop-reduce substitution based on the ROMAN_MAP
while number >= i:
roman_number += r
number -= i
return data[:space_pos + 1] + roman_number # put everything back together
except (TypeError, ValueError):
pass # couldn't extract a number
return data
我们无法轻松地将我们的函数应用于整个列:
HSP_OLD = pd.DataFrame({"tryl": ["SAF/HSP: Secondary diagnosis E code 1",
None,
"SAF/HSP: Secondary diagnosis E code 11",
"Something else without a number at the end"]})
其结果是:
HSP_OLD['tryl'] = HSP_OLD['tryl'].apply(romanize)
当然,您可以根据需要调整romanize函数,以搜索字符串中的任何数字并将其转换为罗马数字-这只是一个如何快速找到字符串末尾数字的示例。标题似乎与代码相反。标题似乎与代码相反。我喜欢您的回答,但我认为如果没有这一行,它也会起同样的作用:当数字>0时:循环减少,同时将数字转换为罗马数字numerals@Zack-你完全正确,它可能在我第一次处理这个问题时就一直存在,我忘记移除残留的环。谢谢你的更正。我喜欢你的答案,但我认为如果没有这一行:while number>0:loop reduce,将我们的数字转换为罗马数字,它也会起同样的作用numerals@Zack-你完全正确,它可能在我第一次处理这个问题时就一直存在,我忘记移除残留的环。谢谢你的更正。