Tôi có nhiệm vụ này mà tôi đã làm việc, nhưng có những hiểu lầm cực đoan về phương pháp của tôi.Phân tích dữ liệu để định dạng chuỗi không nhất quán
Vì vậy, vấn đề là tôi có rất nhiều tệp excel được định dạng lạ (và không nhất quán) và tôi cần trích xuất một số trường nhất định cho mỗi mục nhập. Một bộ dữ liệu ví dụ là
cách tiếp cận ban đầu của tôi là thế này:
- Xuất khẩu sang csv
- riêng biệt vào các quận
- riêng vào huyện
- Phân tích mỗi huyện riêng, kéo các giá trị ngoài số
- ghi vào output.csv
Vấn đề tôi gặp phải là định dạng (dường như được tổ chức tốt) gần như ngẫu nhiên trên các tệp. Mỗi dòng chứa các trường giống nhau, nhưng theo thứ tự, khoảng cách và từ ngữ khác nhau. Tôi đã viết một kịch bản để xử lý chính xác một tệp, nhưng nó không hoạt động trên bất kỳ tệp nào khác.
Câu hỏi của tôi là, có phương pháp tiếp cận vấn đề này mạnh mẽ hơn là xử lý chuỗi đơn giản không? Những gì tôi đã có trong tâm trí là nhiều hơn một cách tiếp cận logic mờ cho cố gắng để pin mà lĩnh vực một mục được, mà có thể xử lý các yếu tố đầu vào là một chút tùy ý. Bạn sẽ tiếp cận vấn đề này như thế nào?
Nếu nó giúp sáng tỏ vấn đề, đây là kịch bản tôi đã viết:
# This file takes a tax CSV file as input
# and separates it into counties
# then appends each county's entries onto
# the end of the master out.csv
# which will contain everything including
# taxes, bonds, etc from all years
#import the data csv
import sys
import re
import csv
def cleancommas(x):
toggle=False
for i,j in enumerate(x):
if j=="\"":
toggle=not toggle
if toggle==True:
if j==",":
x=x[:i]+" "+x[i+1:]
return x
def districtatize(x):
#list indexes of entries starting with "for" or "to" of length >5
indices=[1]
for i,j in enumerate(x):
if len(j)>2:
if j[:2]=="to":
indices.append(i)
if len(j)>3:
if j[:3]==" to" or j[:3]=="for":
indices.append(i)
if len(j)>5:
if j[:5]==" \"for" or j[:5]==" \'for":
indices.append(i)
if len(j)>4:
if j[:4]==" \"to" or j[:4]==" \'to" or j[:4]==" for":
indices.append(i)
if len(indices)==1:
return [x[0],x[1:len(x)-1]]
new=[x[0],x[1:indices[1]+1]]
z=1
while z<len(indices)-1:
new.append(x[indices[z]+1:indices[z+1]+1])
z+=1
return new
#should return a list of lists. First entry will be county
#each successive element in list will be list by district
def splitforstos(string):
for itemind,item in enumerate(string): # take all exception cases that didn't get processed
splitfor=re.split('(?<=\d)\s\s(?=for)',item) # correctly and split them up so that the for begins
splitto=re.split('(?<=\d)\s\s(?=to)',item) # a cell
if len(splitfor)>1:
print "\n\n\nfor detected\n\n"
string.remove(item)
string.insert(itemind,splitfor[0])
string.insert(itemind+1,splitfor[1])
elif len(splitto)>1:
print "\n\n\nto detected\n\n"
string.remove(item)
string.insert(itemind,splitto[0])
string.insert(itemind+1,splitto[1])
def analyze(x):
#input should be a string of content
#target values are nomills,levytype,term,yearcom,yeardue
clean=cleancommas(x)
countylist=clean.split(',')
emptystrip=filter(lambda a: a != '',countylist)
empt2strip=filter(lambda a: a != ' ', emptystrip)
singstrip=filter(lambda a: a != '\' \'',empt2strip)
quotestrip=filter(lambda a: a !='\" \"',singstrip)
splitforstos(quotestrip)
distd=districtatize(quotestrip)
print '\n\ndistrictized\n\n',distd
county = distd[0]
for x in distd[1:]:
if len(x)>8:
district=x[0]
vote1=x[1]
votemil=x[2]
spaceindex=[m.start() for m in re.finditer(' ', votemil)][-1]
vote2=votemil[:spaceindex]
mills=votemil[spaceindex+1:]
votetype=x[4]
numyears=x[6]
yearcom=x[8]
yeardue=x[10]
reason=x[11]
data = [filename,county,district, vote1, vote2, mills, votetype, numyears, yearcom, yeardue, reason]
print "data",data
else:
print "x\n\n",x
district=x[0]
vote1=x[1]
votemil=x[2]
spaceindex=[m.start() for m in re.finditer(' ', votemil)][-1]
vote2=votemil[:spaceindex]
mills=votemil[spaceindex+1:]
votetype=x[4]
special=x[5]
splitspec=special.split(' ')
try:
forind=[i for i,j in enumerate(splitspec) if j=='for'][0]
numyears=splitspec[forind+1]
yearcom=splitspec[forind+6]
except:
forind=[i for i,j in enumerate(splitspec) if j=='commencing'][0]
numyears=None
yearcom=splitspec[forind+2]
yeardue=str(x[6])[-4:]
reason=x[7]
data = [filename,county,district,vote1,vote2,mills,votetype,numyears,yearcom,yeardue,reason]
print "data other", data
openfile=csv.writer(open('out.csv','a'),delimiter=',', quotechar='|',quoting=csv.QUOTE_MINIMAL)
openfile.writerow(data)
# call the file like so: python tax.py 2007May8Tax.csv
filename = sys.argv[1] #the file is the first argument
f=open(filename,'r')
contents=f.read() #entire csv as string
#find index of every instance of the word county
separators=[m.start() for m in re.finditer('\w+\sCOUNTY',contents)] #alternative implementation in regex
# split contents into sections by county
# analyze each section and append to out.csv
for x,y in enumerate(separators):
try:
data = contents[y:separators[x+1]]
except:
data = contents[y:]
analyze(data)
Cách tốt nhất và đáng tin cậy nhất để giải quyết vấn đề này là buộc mọi người cung cấp cho bạn dữ liệu này tuân theo định dạng chuẩn, nhưng tôi không biết đó có phải là tùy chọn có sẵn cho bạn hay không. Nếu không thi hành một số cấu trúc, những người cung cấp dữ liệu này sẽ liên tục phá vỡ chương trình của bạn. –