如何将单词和数字的字符串拆分为单词和数字的列

时间:2019-12-21 18:23:04

标签: python pandas text web-scraping

我正在尝试从文本文件中拆分字符串

"Cost of Goods Sold (COGS) incl. D&A 142.26B 131.51B 141.7B 163.83B 162.26B"
"Depreciation & Amortization Expense 10.5B 9.8B 9.4B 9.3B 11.3B"

插入表格,例如:

Metric                                2019    2018    2017   2016    2015   
Cost of Goods Sold (COGS) incl. D&A:  142.26B 131.51B 141.7B 163.83B 162.26B
Depreciation & Amortization Expense   10.5B   9.8B    9.4B   9.3B    11.3B

我使用了以下命令:

df = pd.read_csv(fileName, sep="\s+", names=['Metric','Y4','Y3','Y2','Y1'])

但是我得到以下输出:

                Metric                        Y4            Y3         Y2          Y1
Cost                          of           Goods          Sold     (COGS)       incl.
COGS                   excluding             D&A        27.56B     26.83B      26.77B
Depreciation                   &    Amortization       Expense      5.48B       5.95B

是否有一种简单的方法可以将此文本拆分为文本+数字?我可以将字符串分成列表并手动重建字符串,但是由于“度量”包含多个字符串,因此变得很复杂。

谢谢!

艾伦

2 个答案:

答案 0 :(得分:2)

我们可以分几个步骤解决这个问题:

  1. 首先,我们在列表(我将其称为file.txt中读取您的文件:
with open('file.txt') as f:
    data = f.read().split('\n')
    print(data)

['Cost of Goods Sold (COGS) incl. D&A 142.26B 131.51B 141.7B 163.83B 162.26B', 'Depreciation & Amortization Expense 10.5B 9.8B 9.4B 9.3B 11.3B']
  1. 我们在空白(split)上' '行,该空白以多个非数字字符开头。为此,我们使用regular expressionspositive lookbehind
import re
df = pd.DataFrame([[value for value in re.split('(\D{2,})\s', line) if value != ''] 
                   for line in data], columns=['Metric', 'Years'])

                                Metric                                   Years
0  Cost of Goods Sold (COGS) incl. D&A  142.26B 131.51B 141.7B 163.83B 162.26B
1  Depreciation & Amortization Expense              10.5B 9.8B 9.4B 9.3B 11.3B
  1. 我们使用Series.splitexpand=True将您的年份分为自己的列:
df = df.join(df.pop('Years').str.split(expand=True))

                                Metric        0        1       2        3        4
0  Cost of Goods Sold (COGS) incl. D&A  142.26B  131.51B  141.7B  163.83B  162.26B
1  Depreciation & Amortization Expense    10.5B     9.8B    9.4B     9.3B    11.3B
  1. 最后,我们将您的列重命名为正确的列:
df.columns = ['Metric'] + list(range(2019, 2014, -1))

                                Metric     2019     2018    2017     2016     2015
0  Cost of Goods Sold (COGS) incl. D&A  142.26B  131.51B  141.7B  163.83B  162.26B
1  Depreciation & Amortization Expense    10.5B     9.8B    9.4B     9.3B    11.3B

答案 1 :(得分:2)

另一种解决方案是使用str.rsplit-用maxsplit=5从右边分割字符串:

import pandas as pd

txt = '''
"Cost of Goods Sold (COGS) incl. D&A 142.26B 131.51B 141.7B 163.83B 162.26B"
"Depreciation & Amortization Expense 10.5B 9.8B 9.4B 9.3B 11.3B"
'''

lines = []
for line in map(str.strip, txt.splitlines()):
    if not line:                                    # skip empty lines
        continue
    lines.append( line[1:-1].rsplit(maxsplit=5) )   # [1:-1] because we want to get rid of quotes (")

df = pd.DataFrame(lines, columns=['Metric', 'Y5', 'Y4', 'Y3', 'Y2', 'Y1'])
print(df)

打印:

                                Metric       Y5       Y4      Y3       Y2       Y1
0  Cost of Goods Sold (COGS) incl. D&A  142.26B  131.51B  141.7B  163.83B  162.26B
1  Depreciation & Amortization Expense    10.5B     9.8B    9.4B     9.3B    11.3B