同时使用 f-string 和 raw string
Using f-string and raw string at same time
我有这样一个数据框:
p q
0 jdkdn 01JAN2020
1 01JAN2020 hdk789dj
2 783i3 01FEB2020
我正在尝试用 01-01-2020
替换 01JAN2020
,基本上是 alphabetical month name
到 numeric month number
。我不知道这些 date
在哪里,意思是在任何列和任何行中。我曾尝试仅使用 df.replace
来完成此操作,但原始字符串有问题,我也想使用 f-string。
这是我的尝试:
import pandas as pd
import re
df=pd.DataFrame({"p":["jdkdn","01JAN2020","783i3"],"q":["01JAN2020","hdk789dj","01FEB2020"]})
months = {'JAN': '01', 'FEB': '02'}
#All 12 months but for test I am using just 2
df.replace(r'(\d{2})('+'|'.join(months)+')(\d{4})',r"-"+
f"{{months[\2]}}" # Here I am trying to do main things
+r"-",regex=True,inplace=True)
print(df)
"""
p q
0 jdkdn 01-{months[JAN]}-2020
1 01-{months[JAN]}-2020 hdk789dj
2 783i3 01-{months[FEB]}-2020
"""
fr"{{months[\2]}}"
"""
p q
0 jdkdn 01-{months[]}-2020
1 01-{months[]}-2020 hdk789dj
2 783i3 01-{months[]}-2020
"""
rf"{months[]}" and rf"{months[\2]}"
"""
SyntaxError: f-string expression part cannot include a backslash
"""
想法:
我们可以像 (?(<month name>)<number>)
一样使用 regex if
吗?pandas 中任何可以检测任何 01JAN2020
的函数将其替换为 01-01-2020
。
预期输出为:
p q
0 jdkdn 01-01-2020
1 01-01-2020 hdk789dj
2 783i3 01-02-2020
您可以使用 pandas 海峡。替换,只需创建一个带有名称和替换的模式,然后使用 transform
将其应用于所有列:
pat = r"(?P<day>\d+)(?P<month>[A-Z]+)(?P<year>\d+)"
repl = lambda m: f"{m.group('day')}-{months[m.group('month')]}-{m.group('year')}"
df.transform(lambda x: x.str.replace(pat, repl, regex=True))
p q
0 jdkdn 01-01-2020
1 01-01-2020 hdk789dj
2 783i3 01-02-2020
注意,对于字符串,如果你想要更高的性能,你可以把它写在python之内并应用。您可以为此使用 re.sub
,它应该会带来明显的改进(请测试):
df.applymap(lambda x: re.sub(pat, repl, x))
如果您的数据是重复的,一种有效的方法是转换为分类并将字符串修改应用于类别;那应该会更快。
请注意,在 python 中,pandas 字符串函数隐含地涵盖了空值,您的代码应该涵盖这些可能的情况。
我有这样一个数据框:
p q
0 jdkdn 01JAN2020
1 01JAN2020 hdk789dj
2 783i3 01FEB2020
我正在尝试用 01-01-2020
替换 01JAN2020
,基本上是 alphabetical month name
到 numeric month number
。我不知道这些 date
在哪里,意思是在任何列和任何行中。我曾尝试仅使用 df.replace
来完成此操作,但原始字符串有问题,我也想使用 f-string。
这是我的尝试:
import pandas as pd
import re
df=pd.DataFrame({"p":["jdkdn","01JAN2020","783i3"],"q":["01JAN2020","hdk789dj","01FEB2020"]})
months = {'JAN': '01', 'FEB': '02'}
#All 12 months but for test I am using just 2
df.replace(r'(\d{2})('+'|'.join(months)+')(\d{4})',r"-"+
f"{{months[\2]}}" # Here I am trying to do main things
+r"-",regex=True,inplace=True)
print(df)
"""
p q
0 jdkdn 01-{months[JAN]}-2020
1 01-{months[JAN]}-2020 hdk789dj
2 783i3 01-{months[FEB]}-2020
"""
fr"{{months[\2]}}"
"""
p q
0 jdkdn 01-{months[]}-2020
1 01-{months[]}-2020 hdk789dj
2 783i3 01-{months[]}-2020
"""
rf"{months[]}" and rf"{months[\2]}"
"""
SyntaxError: f-string expression part cannot include a backslash
"""
想法:
我们可以像 (?(<month name>)<number>)
一样使用 regex if
吗?pandas 中任何可以检测任何 01JAN2020
的函数将其替换为 01-01-2020
。
预期输出为:
p q
0 jdkdn 01-01-2020
1 01-01-2020 hdk789dj
2 783i3 01-02-2020
您可以使用 pandas 海峡。替换,只需创建一个带有名称和替换的模式,然后使用 transform
将其应用于所有列:
pat = r"(?P<day>\d+)(?P<month>[A-Z]+)(?P<year>\d+)"
repl = lambda m: f"{m.group('day')}-{months[m.group('month')]}-{m.group('year')}"
df.transform(lambda x: x.str.replace(pat, repl, regex=True))
p q
0 jdkdn 01-01-2020
1 01-01-2020 hdk789dj
2 783i3 01-02-2020
注意,对于字符串,如果你想要更高的性能,你可以把它写在python之内并应用。您可以为此使用 re.sub
,它应该会带来明显的改进(请测试):
df.applymap(lambda x: re.sub(pat, repl, x))
如果您的数据是重复的,一种有效的方法是转换为分类并将字符串修改应用于类别;那应该会更快。
请注意,在 python 中,pandas 字符串函数隐含地涵盖了空值,您的代码应该涵盖这些可能的情况。