将原始文本转换为csv

时间:2017-02-16 00:47:53

标签: python r csv

我有一个原始数据集(纯文本)。三个样本行如下:

S.11*  N. ENGLAND           L      -8'    21-23  u44'
S.18    TAMPA BAY            W     -7     40-7    u49'
S.25    Buffalo                       L      -4'    18-33  o48

我想将其转换为csv文件。我怎么能这样做? (我更喜欢Python或R)

csv文件应该是这样的:

S, 11, *, N. ENGLAND, L, -8', 21, 23, u44'
S, 18,  , TAMPA BAY, W, -7, 40, 7, u49'
S, 25, ,Buffalo, L, -4', 18-33, o48

3 个答案:

答案 0 :(得分:1)

如果您查看链接到的网页的来源http://www.goldsheet.com/nflog.php,您会看到每行数据都包含在<p>元素中,并且有一个<span>在每个字段之间包含空格。所以源代码看起来像这样(为了清楚起见,我添加了换行符):

<p>
S.11*
<span>&#160;&#160;</span>
N. ENGLAND
<span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span>
L
<span>&#160;&#160;&#160;&#160;&#160;&#160;</span>
-8'
<span>&#160;&#160;&#160;&#160;</span>
21-23
<span>&#160;&#160;</span>
u44'
</p>

这意味着在HTML源代码中,您可以区分分隔字段的空格和城市名称中的空格,这解决了导入此数据的最大问题。因此,最好的策略可能是使用Python中的lxml来解析页面源中的数据。获得每个字段后,您需要进行一些后处理,将第一个字段中的“*”之类的内容拆分为您指定的单独列。然后,您可以轻松地从Python导出到csv。

然而,更大的问题是,这些数据几乎肯定是通过手动输入生成的,这意味着您很可能会随着时间的推移遇到数据中的细微不一致。随着您越来越多地修复这些问题,您的解析代码将因特殊情况而变得沉重。所以你应该考虑一下你想做什么是值得维护这么多代码的努力。

答案 1 :(得分:1)

我使用了前8行数据dor测试。第9行是一个再见,我假设你想要以不同的方式处理它们。如果没有,那么发布问题构造代码,更详细地说明边缘情况。这匹配(letter.period.2nums)(space | asterisk)(空格)(letters.periods,短划线最多15个)的模式,并在阅读之前插入逗号。

read.table(text=sub(
  patt= "^([[:alpha:]]\\.[0-9]{2})([ *])([ ]{1,5})([a-zA-Z .-]{3,15})([ ])", 
  repl= "\\1,\\2,\\4,",
  dat[1:8]) ,
 sep=",", stringsAsFactors=FALSE,quote="\"")
    V1 V2              V3                                     V4
1 S.11  * N. ENGLAND                   L      -8'    21-23  u44'
2 S.18    TAMPA BAY                    W     -7     40-7    u49'
3 S.25    Buffalo                       L      -4'    18-33  o48
4 O.02    L. ANGELES                   L      -9'    13-17  u43'
5 O.06  * San Francisco                 W     -3'    33-21  o43'
6 O.17  * N.Y. JETS                     W     -7'    28-3    u46
7 O.23  * SEATTLE-ot                 L      -1'    6-6      u43'
8 O.30    Carolina                      L      +2'    20-30  o46

这会创建dat项目:

dat <- readLines( textConnection("S.11*  N. ENGLAND           L      -8'    21-23  u44'
S.18    TAMPA BAY            W     -7     40-7    u49'
S.25    Buffalo                       L      -4'    18-33  o48
O.02    L. ANGELES             L      -9'    13-17  u43'
O.06*  San Francisco             W     -3'    33-21  o43'
O.17*  N.Y. JETS                  W     -7'    28-3    u46
O.23*  SEATTLE-ot              L      -1'    6-6      u43'
O.30    Carolina                      L      +2'    20-30  o46
N.06    Bye
N.13    S. FRAN.                    L      -13'   23-20  u47
N.20    Minnesota                   L      +2    24-30  o40
N.27    Atlanta                        L      +4    19-38  o49'
D.04    WASH.                       W     -2'    31-23  o48'
D.11    Miami                         L      -2     23-26  o44
D.18    N. ORLEANS            L      -3     41-48  o48'
D.24    Seattle                         W     +8    34-31  o43'
J.01     Los Angeles                W     -7     44-6    o39'"))

解析尾随材料的最后一步可能是另一次调用read.table,这次只使用默认的空格分隔符。如果您需要逐行解析,还可以使用scan - 函数:

> read.table(text=dat2$V4)
  V1  V2    V3   V4
1  L -8' 21-23 u44'
2  W  -7  40-7 u49'
3  L -4' 18-33  o48
4  L -9' 13-17 u43'
5  W -3' 33-21 o43'
6  W -7'  28-3  u46
7  L -1'   6-6 u43'
8  L +2' 20-30  o46

答案 2 :(得分:1)

您可以使用csv模块执行其中的一部分,并在开始时手动处理非常混乱的字段。

所以,假设您使用的是Python 3.x,这就是我的意思:

import csv

input_filename = 'raw_dataset.txt'
output_filename = 'spreads.csv'

with open(input_filename, 'r', newline='') as infile, \
     open(output_filename, 'w', newline='') as outfile:
    reader = csv.reader(infile, delimiter=' ', skipinitialspace=True)
    writer = csv.writer(outfile, delimiter=',')
    for row in reader:
        new_cols = row[0].split('.')
        if not new_cols[1].endswith('*'):
            new_cols.extend([''])
        else:
            new_cols[1] = new_cols[1][:-1]
            new_cols.extend(['*'])
        row = new_cols + row[1:]
        #print(row)
        writer.writerow(row)

生成的csv输出文件的内容:

S,11,*,N.,ENGLAND,L,-8',21-23,u44'
S,18,,TAMPA,BAY,W,-7,40-7,u49'
S,25,,Buffalo,L,-4',18-33,o48
O,02,,L.,ANGELES,L,-9',13-17,u43'
O,06,*,San,Francisco,W,-3',33-21,o43'
O,17,*,N.Y.,JETS,W,-7',28-3,u46
O,23,*,SEATTLE-ot,L,-1',6-6,u43'
O,30,,Carolina,L,+2',20-30,o46
N,06,,Bye
N,13,,S.,FRAN.,L,-13',23-20,u47
N,20,,Minnesota,L,+2,24-30,o40
N,27,,Atlanta,L,+4,19-38,o49'
D,04,,WASH.,W,-2',31-23,o48'
D,11,,Miami,L,-2,23-26,o44
D,18,,N.,ORLEANS,L,-3,41-48,o48'
D,24,,Seattle,W,+8,34-31,o43'
J,01,,Los,Angeles,W,-7,44-6,o39'