2019년 11월 24일 일요일

python 에서 csv 읽기시 주의점


앞에서 CSV 파일을 좀 더 완벽하게 읽을려고 노력하였습니다. ' " ' 가능한 처리는 아래를 봐주세요.
https://swlock.blogspot.com/2019/11/python-csv.html

그러나 여기에도 문제점이 있습니다. 바로 문자열에 분리하는 문자 ',' 가 들어 있는 경우 입니다. 예를 들어 아래와 같은 데이터가 있습니다.
"hello",""he,""llo","me"
사람이 봐도 약간 혼란 스러울수 있습니다만, "hello"    ""he,""llo"   "me"  3개로 이루어진 데이터 입니다.
"hello",   ""he,""llo,   "me"
알아보기 쉽게 위와 같이 데이터를 만들었습니다. 

결론부터 정리하자면 완벽하게 처리가능한 것은 없었습니다. 한라인씩 직접 읽어서 처리할수 있도록 만들어야 합니다.


제가 이것 저것 변경해본 예제를 여기에 기록하였습니다.

import csv
with open('1.csv', encoding='utf-8') as csvfile:
 reader = csv.reader(csvfile, delimiter=',', quotechar='"')
 for row in reader:
  print(len(row),row)

print("===")

with open('1.csv', encoding='utf-8') as csvfile:
 reader = csv.reader(csvfile, delimiter=',', quotechar='"',doublequote=False)
 for row in reader:
  print(len(row),row)

print("===")

with open('1.csv', encoding='utf-8') as csvfile:
 reader = csv.reader(csvfile, delimiter=',', quotechar='"', quoting = csv.QUOTE_NONE)
 for row in reader:
  print(len(row),row)

print("===")

with open('1.csv', encoding='utf-8') as csvfile:
 reader = csv.reader(csvfile, delimiter=',', quotechar='"', quoting = csv.QUOTE_NONE)
 for row in reader:
  newlist = []
  for value in row:
   if type(value)==str and value.startswith('"') and value.endswith('"'):
    newlist.append(value[1:len(value)-1])
   else:
    newlist.append(value)
  print(len(row),newlist)
print("===newline===")

import pandas

data = pandas.read_csv("1.csv",delimiter=',',encoding="utf-8",engine='c')
print (data)
print (data.shape[1])

print("===newline===")

data = pandas.read_csv("1.csv",quotechar='"', quoting=1, doublequote=True, delimiter=',',encoding="utf-8",engine='c')
print (data)
print (data.shape[1])
print("===newline===")

data = pandas.read_csv("1.csv",dialect='excel', delimiter=',',encoding="utf-8",engine='python')
print (data)
print (data.shape[1])
print("===newline===")

data = pandas.read_csv("1.csv",delimiter=',',encoding="utf-8",engine='python')
print (data)
print (data.shape[1])

결과
크기가 3이 나와야 하나 4가 나오거나 에러가 발생합니다.
4 ['hello', '   ""he', 'llo', '   "me"']
0 []
===
4 ['hello', '   ""he', 'llo', '   "me"']
0 []
===
4 ['"hello"', '   ""he', '""llo', '   "me"']
0 []
===
4 ['hello', '   ""he', '""llo', '   "me"']
0 []
===newline===
Empty DataFrame
Columns: [hello,    ""he, llo,    "me"]
Index: []
4
===newline===
Empty DataFrame
Columns: [hello,    ""he, llo,    "me"]
Index: []
4
===newline===
Traceback (most recent call last):
  File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\site-packages\pandas\io\parsers.py", line 2933, in _next_iter_line
    return next(self.data)
_csv.Error: ',' expected after '"'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\USER\Documents\python\excel\csvread.py", line 48, in <module>
    data = pandas.read_csv("1.csv",dialect='excel', delimiter=',',encoding="utf-8",engine='python')
  File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\site-packages\pandas\io\parsers.py", line 685, in parser_f
    return _read(filepath_or_buffer, kwds)
  File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\site-packages\pandas\io\parsers.py", line 457, in _read
    parser = TextFileReader(fp_or_buf, **kwds)
  File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\site-packages\pandas\io\parsers.py", line 895, in __init__
    self._make_engine(self.engine)
  File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\site-packages\pandas\io\parsers.py", line 1147, in _make_engine
    self._engine = klass(self.f, **self.options)
  File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\site-packages\pandas\io\parsers.py", line 2310, in __init__
    ) = self._infer_columns()
  File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\site-packages\pandas\io\parsers.py", line 2593, in _infer_columns
    line = self._buffered_line()
  File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\site-packages\pandas\io\parsers.py", line 2776, in _buffered_line
    return self._next_line()
  File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\site-packages\pandas\io\parsers.py", line 2873, in _next_line
    orig_line = self._next_iter_line(row_num=self.pos + 1)
  File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\site-packages\pandas\io\parsers.py", line 2956, in _next_iter_line
    self._alert_malformed(msg, row_num)
  File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\site-packages\pandas\io\parsers.py", line 2914, in _alert_malformed
    raise ParserError(msg)
pandas.errors.ParserError: ',' expected after '"'


꼭 csv 파일을 사용할때 데이터에 '"' ',' 와 같은 특수 문자가 포함되어 있는지 확인하고 사용하도록 합니다.




댓글 없음:

댓글 쓰기