(파이썬) 6장 데이터 로딩, 저장 , 파일 형식
*일반적으로 입출력은 몇가지 작은 범주로 나눌 수 있으며 텍스트 파일을 이용하는 방법, 데이터베이스를 이용하는 방법, 웹 API를 이용해서 네트워크를 불러오는 방법이있다.
1. 텍스트 파일 이용하는 방법
*pandas 파일 파싱 함수
read_csv : 파일,URL 또는 파일과 유사한 객체로부터 구분된 데이터를 읽어온다. 데이터 구분자는 쉼표(,)를 기본으로 한다.
read_table: 파일, URL , 또는 파일과 유사한 객체로r부터 구분된 데이터를 읽어온다. 데이터 구분자는 탭('\t')을 기본으로 한다.
read_fwf : 고정폭 칼럼 형식에서 데이터를 읽어온다.(구분자가 없는 데이터)
read_clippboard: 클립보드에 있는 데이터를 읽어오는 read_table함수, 웹페이지에서 표를 긁어올 때 유용하다.
-->위 함수는 DataFrame으로 읽어오는 함수로, 몇가지 종류의 옵션을 받는다.
reader=csv.reader(f,dialect-my_dialect)
**서브클래스를 정의하지 않고, csv.reader에 키워드 인자로 각 CSV파일의 특징을 지정해서 전달해도 된다.
reader=csv.reader(f, delimiter='|')
<CSV관련 옵션>
1. delimiter : 필드를 구분하기 위한 한글자 짜리 구분자. 기본값은 ','
2. lineterminator : 파일을 저장할 때 사용할 개행문자. 기본값은 '\r\n'. 파일을 읽을 때는 이 값을 무시하며 자동으로 플랫폼별 개행문자를 인식한다.
3. quotechar : 각 필드에서 값을 둘러싸고 있는 문자.기본값은 ' " '
4. quoting : 값을 읽거나 쓸 때 둘러쌀 문자 컨벤션. csv.QUOTE_ALL(모든 필드에 적용), csv.QUOTE_MINIMAL(구분자 같은 특별한 문자가 포함된 필드만 적용), csv.QUOTE_NONE(값을 둘러싸지 않음)
5. skipinitialspace : 구분자 뒤에 있는 공백문자를 무시할지의 여부, 기본값은 False
6. doublequote : 값을 둘러싼느 문자가 필드 내에 존재할 경우의 처리 여부. True면 그 문자까지 모두 둘러싼다.
7. escapechar : quoting이 csv.QUOTE_NONE일때, 값에 구분자와 같은 문자가 있을 경우 구별할 수 있또록 해주는 이스케이프 문자('\'같은) ,기본값은 None
*****좀더 복잡하거나 구분자가 한글자를 초과하는 고정 길이를 가진다면 csv모듈을 사용할 수 없다. 이런 경우에는 줄을 나누고 문자열의 split메소드나 정규표현식 메소드인 re.split등을 이용해서 가공하는 작업을 해야 한다.
**CSV같은 구분자로 구분된 파일을 기록하려면 csv.writer를 이용하면 된다. csv.writer는 이미 열린,쓰기가 가능한 파일 객체를 받아서 csv.reader 와 동일한 옵션으로 파일을 기록한다
예)
with open ('mydata.csv', 'w') as f:
writer=csv.writer(f,dialect=my_dialect)
writer.writerow(('one','two','three'))
writer.writerow(('1','2','3'))
writer.writerow(('4','5','6'))
writer.writerow(('7','8','9'))
1. 텍스트 파일 이용하는 방법
*pandas 파일 파싱 함수
read_csv : 파일,URL 또는 파일과 유사한 객체로부터 구분된 데이터를 읽어온다. 데이터 구분자는 쉼표(,)를 기본으로 한다.
read_table: 파일, URL , 또는 파일과 유사한 객체로r부터 구분된 데이터를 읽어온다. 데이터 구분자는 탭('\t')을 기본으로 한다.
read_fwf : 고정폭 칼럼 형식에서 데이터를 읽어온다.(구분자가 없는 데이터)
read_clippboard: 클립보드에 있는 데이터를 읽어오는 read_table함수, 웹페이지에서 표를 긁어올 때 유용하다.
-->위 함수는 DataFrame으로 읽어오는 함수로, 몇가지 종류의 옵션을 받는다.
- 색인: 반환하는 DataFrame에서 하나 이상의 칼럼을 색인으로 지정할 수 있다. 파일이나 사용자로부터 칼럼의 이름을 받거나 아무것도 받지 않을 수 있다.
- 자료형 추론과 데이터 변환: 사용자가 정의 값 변환과 비어 있는 값을 위한 사용자 리스트를 포함한다.
- 날짜분석: 여러 칼럼에 걸쳐 있는 날짜와 시간 정보를 하나의 칼럼에 조합해서 결과에 반영한다.
- 반복: 여러 파일에 걸쳐 있는 자료를 반복적으로 읽어 올 수 있다.
예)
!cat ch06/ex1.csv
a,b,c,d,message
1,2,3,4,hello
5,6,7,8,world
9,10,11,12,foo
**이 파일은 쉼표로 구분되어 있기 때문에 read_csv를 사용해 DataFrame으로 읽어 올 수 있다.
예) df=pd.read_csv('ch06/ex1.csv')
출력:
a b c d message
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo
**read_table에 구분자를 쉼표로 지정해서 읽어올 수 있다.
예) pd.read_table('ch06/ex1.csv',sep=',')
**모든 파일에 칼럼의 이름이 있는건 아니다.
예) 1,2,3,4,hello
5,6,7,8,world
9,10,11,12,foo
이 파일을 직접 읽어오려면 몇가지 옵션이 있는데 ,pandas가 자동으로 칼럼이름을 생성하도록 하거나 직접 칼럼이름을 지정할 수도 있다.
예) pd.read_csv('ch06/ex2.csv',header=None)
또는
pd.read_csv('ch06/ex2.csv',names=['a','b','c','d','message'])
a b c d message
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo
** message 칼럼을 색인으로 하는 DataFrame을 반환하려면 index_col 인자에 네 번째 또는 'message'라는 이름을 가진 칼럼을 지정해서 색인으로 만들 수 있다.
예) names=['a','b','c','d','message']
pd.read_csv('ch06/ex2.csv', names=names, index_col='message')
a b c d
message
hello 1 2 3 4
world 5 6 7 8
foo 9 10 11 12
** 가끔 고정된 구분자 없이 공백이나 다른 패턴으로 필드르 구분해 놓는 경우가 있는데, 이럴떄는 read_table의 구분자로 정규표현식을 사용한다.
다음과 같은 파일이 있다고 가정하자
예) list(open('ch06/ex3.txt'))
[ A B C\n
aaa 0 1 2\n
bbb 3 4 5\n
ccc 6 7 8\n
ddd 9 10 11\n]
-->직접 파일을 고쳐도 되지만 이 파일은 여러 개의 공백문자로 필드가 구분되어 있으므로 이를 표현할 수 있는 정규표현식 \s+를 사용해서 처리할 수 있다.
예) result=pd.read_table('ch06/ex3.txt',sep='\s+')
-->이 경우 첫 번쨰 로우는 다른 로우보다 칼럼이 하나 적기 때문에 read_table은 첫번째 칼럼이 DataFrame의 색인이 되어야 한다고 추론한다.
파서 함순느 파일 형식에서 발생할 수 있는 매우 다양한 예외를 처리할 수 있도록 추가 인자를 가지고 있는데, 예를들면 skiprows를 이용해서 첫번째, 두번째, 네번째 로우를 건너 뛸 수 있다.
예) pd.read_csv('ch06/ex4.csv',skiprows=[0,2,3])
**누락된 값을 잘 처리하는 일은 파일을 읽는 과정에서 자주 발생하는 일이다. 보통 텍스트 파일에서 누락된 값은 표기되지 않거나 (비어있는 문자열) 구분하기 쉬운 특수한 문자로 표기 된다. 기본적으로 pandas는 NA, -1, #IND, NULL 처럼 비어있는 값으로 흔히 통용되는 문자를 인식해서 비어있는 값으로 처리한다.
** na_values 옵션은 리스트나 문자열 집합을 받아서 누락된 값을 처리한다.
예) result=pd.read_csv('ch06/ex5.csv', na_values=['NULL'])
출력:
something a b c d message
0 one 1 2 3 4 hello
1 two 5 6 NaN 8 world
2 three 9 10 11 12 foo
<<read_csv/ read_table 함수 인자>>
1. path : 파일시스템에서의 위치, URL, 파일 객체를 나타내는 문자열
2. sep or delimiter : 필드를 구분하기 위해 사용할 연속된 문자나 정규표현식
3. header : 칼럼이 이름으로 사용할 로우의 번호 기본 값은 0(첫 로우) 이며 헤더가 없으면 None으로 지정할 수 있다.
4. index_col : 색인으로 사용할 칼럼번호나 이름, 계층적 색인을 지정할 경우 리스트를 넘길 수 있다.
5. names : 칼럼의 이름으로 사용할 리스트,header=None과 함께 사용한다.
6. skiprows : 파일의 시작부터 못할 로우의 개수 또는 무시할 로우번호가 담긴 리스트
7. na_values : NA값으로 처리할 값들의 나열
8. comment : 주석으로 분류되어 파싱하지 않을 문자 혹은 문자열
9. parse_dates : 날짜를 datetime으로 변환할지의 여부, 기본값은 False이며 True일 경우 모든 칼럼에 다 적용된다. 리스트를 넘기면 변환할 칼럼을 지정할 수 있는데, [1,2,3]을 넘기면 각각의 칼럼을 datetime으로 변환하고, [[1,3]]을 넘기면 1,3 번 칼럼을 조합해서 하나의 datetime으로 변환한다.
10. keep_date_col : 여러 칼럼을 datetime으로 변환했을 경우 원래 칼럼을 남겨둘지의 여부, 기본 값은 False
11. converters : 변환시 칼럼에 적용할 함수를 지정한다. 예를들어, {'foo': f}는 'foo'칼럼에 f함수를 적용한다. 전달하는 사전의 키 값은 칼럼이름이나 번호가 될 수 있다.
12. dayfirst : 모호한 날짜 형식일 경우 국제형식으로 간주한다.(7/6/2012는 2012년 6월 7일로 간주한다). 기본값은 False
13. date_parser : 날짜 변환시 사용할 ㅎㅁ수
14. nrows : 파일의 첫 일부만 읽어올 때 처음 몇줄을 읽을 것인지 지정한다.
15. iterator : 파일을 조금씩 읽을 때 사용하도록 TextParser객체를 반환하도록 한다. 기본값은 False
16. chunksize : TextParser 객체에서 사용할, 한번에 읽을 파일의 크기
17. skip_footer : 무시할 파일의 마지막 줄 수
18. verbose : 파싱 결과에 대한 정보를 출력한다. 숫자가 아닌 값이 들어있는 칼럼이면서 누락된 값이 있다면 줄 번호를 출력한다. 기본값은 False
19. encoding : 유닠드 인코딩 종류를 지정한다.UTF-8로 인코딩된 텍스트일 경우 'utf-8'로 지정한다.
20. squeeze : 로우가 하나뿐이라면 Series객체를 반환한다. 기본값은 False
21. thousands : 숫자를 천 단위로 끊을 때 ',' 나'.' 같은 구분자
<2. 텍스트 파일 조금씨 읽어오기>
*파일을 전체를 읽는 대신 처음 몇줄만 읽어보고 싶다면 nrows옵션을 주면된다.
예)
pd.read_csv('ch06/ex6.csv', nrows=5)
*파일을 여러 조각에 나누어서 읽고 싶다면 chunksize옵션으로 로우의 개수를 주면된다.
chunker=pd.read_csv('ch06/ex6.csv', chunksize=1000)
*read_csv 에서 반환된 TextParser 객체를 이용해서 chunksize에 따라 분리된 파일을 순회 할 수 있다. 예를들어, ex6.csv 파일을 순회하면서 'key' 칼럼에 있는 값을 세어보려면 다음처럼 하면된다.
예)chunker=pd.read_csv('ch06/ex6.csv', chunksize=1000)
tot=Series([])
for piece in chunker:
tot=tot.add(piece['key'].value_counts(), fill_value=0)
tot=tot.order(ascending=False)
tot[:10]
출력:
E 368
X 364
L 346
O 343
Q 340
M 338
J 337
F 335
K 334
H 330
<3. 데이터를 텍스트 형식으로 기록하기>
**읽어오기와 마찬가지로 데이터를 구분자로 구분된 형시긍로 내보내는 것도 가능하다.
예) data.to_csv('ch06/out.csv')
*구분자를 사용하는 것도 가능하다.
예)
data.to_csv(sys.stdout, sep='|')
** 결과에서 누락된 값은 비어있는 문자열로 나타내는데, 이것 역시 웒는 값으로 지정할 수 있다.
예) data.to_csv(sys.stdout, na_rep='NULL')
결과:
,somthing,a,b,c,d,message
0,one,1,2,3.0,4,NULL
1,two,5,6,NULL,8,world
2,three,9,10,11.0,12,foo
**다른 옵션이 명시되지 않으면 로우와 칼럼의 이름도 함께 기록된다. 로우와 칼럼의 이름을 포함하지 않으면 다음과 같이 사용한다.
예)
data.to_csv(sys.stdout, index=False, header=False)
**칼럼의 일부분만 기록할 수도 있고, 순서를 직접 지정할 수도 있다.
예)
data.to_csv(sys.stdout, index=False, cols=['a','b','c'])
**Series에도 to_csv메소드가 있다.
예)
dates=pd.date_range('1/1/2000', periods=7)
ts=Series(np.arange(7), index=dates)
ts.to_csv('ch06/tseries.csv')
결과:
2000-01-01 00:00:00,0
.
.
.
2000-01-07 00:00:00.,6
**약간 복잡하게 헤더를 없애고 첫 번째 칼럼을 색인으로 하면 read_csv메소드로 Series객체를 얻을 수 있지만 from_csv메소드가 좀더 편리하고 간단하게 문제를 해결해준다.
예)
Series.from_csv('ch06/tseries.csv', parse_date=True)
2000-01-01 0
...
...
..
2000-01-07 6
<4. 수동으로 구분 형식 처리하기>
**간혹 read_table에서 읽을 수 없는 잘못된 형식의 줄이 포함된 데이터는 드물지 않게 발견할 수 있다.
다음 CSV파일을 보자.
"a","b","c"
"1","2","3"
"1","2","3","4"
**구분자가 한글자인 파일은 파이썬 내장 csv모듈을 이용해서 처리할 수 있는데, 열려진 파일 객체를 csv.reader함수에 넘기기만 하면된다.
예)
import csv
f=open('ch06/ex7.csv')
reader=csv.reader(f)
--->파일을 읽듯이 reader를 순회하면 둘러싸고 있던 큰따옴표(")가 제거된 튜플을 얻을 수 있다.
**CSV파일은 다양한 형태로 존재할 수 있는데 다양한 구분자, 문자열을 둘러싸는 방법, 개행문자 같은 것은 csv.Dialect를 상속받아 새로운 클래스를 정의해서 해결할 수 있다.
예)
class my_dialect(csv.Dialect):
lineterminator='\n'
delimiter=';'
quotechar=' " '
다음 CSV파일을 보자.
"a","b","c"
"1","2","3"
"1","2","3","4"
**구분자가 한글자인 파일은 파이썬 내장 csv모듈을 이용해서 처리할 수 있는데, 열려진 파일 객체를 csv.reader함수에 넘기기만 하면된다.
예)
import csv
f=open('ch06/ex7.csv')
reader=csv.reader(f)
--->파일을 읽듯이 reader를 순회하면 둘러싸고 있던 큰따옴표(")가 제거된 튜플을 얻을 수 있다.
**CSV파일은 다양한 형태로 존재할 수 있는데 다양한 구분자, 문자열을 둘러싸는 방법, 개행문자 같은 것은 csv.Dialect를 상속받아 새로운 클래스를 정의해서 해결할 수 있다.
예)
class my_dialect(csv.Dialect):
lineterminator='\n'
delimiter=';'
quotechar=' " '
reader=csv.reader(f,dialect-my_dialect)
**서브클래스를 정의하지 않고, csv.reader에 키워드 인자로 각 CSV파일의 특징을 지정해서 전달해도 된다.
reader=csv.reader(f, delimiter='|')
<CSV관련 옵션>
1. delimiter : 필드를 구분하기 위한 한글자 짜리 구분자. 기본값은 ','
2. lineterminator : 파일을 저장할 때 사용할 개행문자. 기본값은 '\r\n'. 파일을 읽을 때는 이 값을 무시하며 자동으로 플랫폼별 개행문자를 인식한다.
3. quotechar : 각 필드에서 값을 둘러싸고 있는 문자.기본값은 ' " '
4. quoting : 값을 읽거나 쓸 때 둘러쌀 문자 컨벤션. csv.QUOTE_ALL(모든 필드에 적용), csv.QUOTE_MINIMAL(구분자 같은 특별한 문자가 포함된 필드만 적용), csv.QUOTE_NONE(값을 둘러싸지 않음)
5. skipinitialspace : 구분자 뒤에 있는 공백문자를 무시할지의 여부, 기본값은 False
6. doublequote : 값을 둘러싼느 문자가 필드 내에 존재할 경우의 처리 여부. True면 그 문자까지 모두 둘러싼다.
7. escapechar : quoting이 csv.QUOTE_NONE일때, 값에 구분자와 같은 문자가 있을 경우 구별할 수 있또록 해주는 이스케이프 문자('\'같은) ,기본값은 None
*****좀더 복잡하거나 구분자가 한글자를 초과하는 고정 길이를 가진다면 csv모듈을 사용할 수 없다. 이런 경우에는 줄을 나누고 문자열의 split메소드나 정규표현식 메소드인 re.split등을 이용해서 가공하는 작업을 해야 한다.
**CSV같은 구분자로 구분된 파일을 기록하려면 csv.writer를 이용하면 된다. csv.writer는 이미 열린,쓰기가 가능한 파일 객체를 받아서 csv.reader 와 동일한 옵션으로 파일을 기록한다
예)
with open ('mydata.csv', 'w') as f:
writer=csv.writer(f,dialect=my_dialect)
writer.writerow(('one','two','three'))
writer.writerow(('1','2','3'))
writer.writerow(('4','5','6'))
writer.writerow(('7','8','9'))
댓글
댓글 쓰기