我目前正在清理一个凌乱的数据表,在一个Excel单元格中给出信息,该单元格中不区分不同的特征(没有逗号,空格是随机的)。 因此,我的问题是要分隔不同的信息,而不能在代码中使用分隔符(不能使用split命令)
我假设我需要包括信息各部分的某些特征,以便识别相应的特征。但是,我不知道如何执行此操作,因为我是Python的新手,我只在回归模型和其他统计分析的框架中使用R。
短数据示例: 输入:
"WMIN CBOND12/05/2022 23554132121"
或
“ WalMaInCBND 12/05 / 2022-23554132121”
或
“ WalmartI CorpBond12 / 05/2022 | 23554132121”
预期输出:
"Walmart Inc.", "Corporate Bond", "12/05/2022", "23554132121"
因此,每个“ x”都应在新列中分类,并带有相应的标题(公司,安全性,到期日,帐号)
您可以看到输入是随机变化的,但是我希望上面给出的三个输入中的每个输入都具有相同的输出(我拥有超过20万个数据点,分别来自不同的公司,证券等)
第一个问题是如何在不使用系统模式的情况下有效地分离信息。
第二个问题(优先级较低)是如何识别公司,而无需为50k公司设置具有50种不同输入的字典。
感谢您的帮助!
答案 0 :(得分:0)
修改
s = c("WMIN CBOND12/05/2022 23554132121",
"WalMaInCBND 12/05/2022-23554132121",
"WalmartI CorpBond12/05/2022|23554132121")
ID = gsub("([a-zA-Z]+).*","\\1",s)
ID2 = gsub(".* ([a-zA-Z]+).*","\\1",s)
date = gsub("[a-zA-Z ]+(\\d+\\/\\d+\\/\\d+).*","\\1",s)
num = gsub("^.*[^0-9](.*$)","\\1",s)
data.frame(ID=ID,ID2=ID2,date=date,num=num,stringsAsFactors=FALSE)
ID ID2 date num
1 WMIN CBOND 12/05/2022 23554132121
2 WalMaInCBND WalMaInCBND 12/05/2022-23554132121 12/05/2022 23554132121
3 WalmartI CorpBond 12/05/2022 23554132121
适用于情况1和3,但是我还没有弄清楚第二种情况的逻辑,如果不将包含公司和安全性的字符串分开,我们如何知道在何处分割呢?
答案 1 :(得分:0)
使用python和正则表达式:
import re
def make_filter(pattern):
pattern = re.compile(pattern)
def filter(s):
filtered = pattern.match(s)
return filtered.group(1), filtered.group(2), filtered.group(3), filtered.group(4)
return filter
filter = make_filter("^([a-zA-Z]+)\s([a-zA-Z]+)(\d+/\d+/\d+)\s(\d+)$")
filter("WMIN CBOND12/05/2022 23554132121")
make_filter
函数只是一个允许您修改模式的实用程序。它返回一个函数,该函数将根据该模式过滤输出。我将其与"^([a-zA-Z]+)\s([a-zA-Z]+)(\d+/\d+/\d+)\s(\d+)$"
模式一起使用,该模式考虑了一些文本,一个空格,一些文本,一个日期,一个空格和一个数字。如果要整理此模式,请提供有关它的更多信息。输出将为("WMIN", "CBOND", "12/05/2022", "23554132121")
。
答案 2 :(得分:0)
我建议首先尽可能引入有用的分隔符,并构造一个替换字典以使用正则表达式进行处理。
import re
s = 'WMIN CBOND12/05/2022 23554132121'
# CAREFUL this not a real date regex, this should just
# illustrate the principle of regex
# see https://stackoverflow.com/a/15504877/5665958 for
# a good US date regex
date_re = re.compile('([0-9]{2}/[0-9]{2}/[0-9]{4})')
# prepend a whitespace before the date
# this is achieved by searching the date within the string
# and replacing it with itself with a prepended whitespace
# /1 means "insert the first capture group", which in our
# case is the date
s = re.sub(date_re, r' \1', s)
# split by one or more whitespaces and insert
# a seperator (';') to make working with the string
# easier
s = ';'.join(s.split())
# build a dictionary of replacements
replacements = {
'WMIN': 'Walmart Inc.',
'CBOND': 'Corporate Bond',
}
# for each replacement apply subsitution
# a better, but more replicated solution for
# this is given here:
# https://stackoverflow.com/a/15175239/5665958
for pattern, r in replacements.items():
s = re.sub(pattern, r, s)
# use our custom separator to split the parts
out = s.split(';')
print(out)
答案 3 :(得分:0)
欢迎光临!是的,我们当然需要查看更多示例,而正则表达式似乎是要走的路...但是由于似乎没有结构,所以我认为最好将其视为单独的步骤。
(X)X/(X)X/XXXX
(例如,一两位数的日期,一两位数的月份,四位数的年份,可能带有或不带有斜杠,对吗?),然后是数字。因此,首先解决该部分,仅保留前两个类别。这实际上是简单的部分:),但不要灰心!WMINCBOND 12/05/202223554132121
,或者分隔符并不总是例如IMAGINARY COMPANY X CBOND
的分隔符,那么您就陷入了麻烦。:)但是,这就是我们可以做:
str_detect()
,看看是否可以识别任何数据集中的确切字符串(如果确实有代码lemme,我将编写代码来完成这一部分)。 CBOND
,不管是什么……最后做那部分……字符串的剩下就是那个。另外,如果您拥有str_detect()
的所有内容列表,则可以使用相同的CBOND
。