我有一个原始数据集(纯文本)。三个样本行如下:
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
答案 0 :(得分:1)
如果您查看链接到的网页的来源http://www.goldsheet.com/nflog.php,您会看到每行数据都包含在<p>
元素中,并且有一个<span>
在每个字段之间包含空格。所以源代码看起来像这样(为了清楚起见,我添加了换行符):
<p>
S.11*
<span>  </span>
N. ENGLAND
<span>           </span>
L
<span>      </span>
-8'
<span>    </span>
21-23
<span>  </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'