- 문자열을 시계열 데이터로 변환
df=pd.read_csv('./data/stock-data.csv') print(df.head()) df.info() # date는 날짜 데이터 같은데 object type으로 되어있다.
# 날짜 자료형을 변경해서 새로운 필드로 저장하기 df['NewDate']=pd.to_datetime(df['Date']) df.info()
# 새로 만들어진 날짜 컬럼을 인덱스로 지정하고 기존의 날짜 컬럼 삭제 df.set_index(df['NewDate'], inplace=True) df.drop('Date',axis=1, inplace=True) df.head()
- 여기에 샘플 데이터를 추가해보자.
# 첫 번째 데이터는 날짜로 변경 가능한 데이터 # 두 번째 데이터는 날짜로 변경 불가능한 데이터 (TM 오타) date_strings=np.array([ '03-04-2005 11:35 PM', '04-09-2005 09:09 TM'])
# 첫 번째 데이터는 날짜로 변경 가능한 데이터 # 두 번째 데이터는 날짜로 변경 불가능한 데이터 (TM 오타) date_strings=np.array([ '03-04-2005 11:35 PM', '04-09-2005 09:09 TM']) # 예외 발생 # print([pd.to_datetime(date, format='%d-%m-%Y %I:%M %p') for date in date_strings]) # errors 관련 (예외) 옵션이 존재한다. print([pd.to_datetime(date, format='%d-%m-%Y %I:%M %p', errors='ignore') for date in date_strings])
[Timestamp('2005-04-03 23:35:00'), '04-09-2005 09:09 TM']
- 두 개가 다르게 나옵니다.
- list는 2개의 데이터 자료형이 달라도 상관없지만,
array나 DF으로 변환해서 사용하는 경우에는 문제가 생길 수 있습니다.4print([pd.to_datetime(date, format='%d-%m-%Y %I:%M %p', errors='coerce') for date in date_strings]) # 변환이 되지 않는 경우에는 coerce는 NaT로 변환해버림 # 이러면 array나 df 변환 시 datatype은 보존할 수 있다.
print([pd.to_datetime(date, format='%d-%m-%Y %I:%M %p', errors='raise') for date in date_strings]) # errors='raise'는 default로 처음과 같이 # 에러가 발생하면 예외발생처리하고 종료해버린다.
- 일정한 기간을 의미하는 Period
- 날짜 데이터를 일정한 간격 단위로 사용하고자 할 때 사용하는 자료형
- pd의 to_period 함수를 이용하는데, freq 옵션에 주기를 설정함D : 일 W : 주 M : 1개월(월말) MS : 1개월(월초 Q : 분기말 QS : 분기초 A : 연말 AS : 연초 B : 월화수목금 H : 1시간 T : 1분 S : 1초 L : 1밀리초 U : 1마이크로초 N : 1나노초
date_strings=np.array([ '2023-01-01', '2023-02-02','2023-02-20', '2023-04-05']) pddates=pd.to_datetime(date_strings) pr_months=pddates.to_period(freq='M') pr_months # 이렇게 된다면 '일' 이 잘리고 '월' 까지만 남는다.
- 주기를 갖는 날짜 생성
date_range 함수 이용합니다. - start : 시작 날짜 - end : 종료 날짜 - periods : 생성할 날짜 개수 - freq : 주기 - tz : 시간대 설정('Asia/Seoul') - tz는 시간대역이고 중요한 정보이기에 거의 생략을 못함
- 일정한 주기를 가지고 데이터가 생성되는데, 생성된 시간을 알지 못하는 경우 사용
- 시작 시간만 알고 있는 경우
# 2023년 1월 1일부터 월 단위로 12개를 생성해보고 싶어 ts_ms=pd.date_range(start='2023-01-01', periods=12, freq='MS', # 월초 tz='Asia/Seoul') print(ts_ms)
- 년월일 분리
- datetime64 타입에서 dt.단위에 해당하는 속서응ㄹ 호출
- 년도를 추출하고자 하는 경우에는 dt.year- 날짜 차이
- datetime64는 뺄셈을 연산자 오버로딩을 해놓았기 때문에 가능함
- datetime64를 인덱스로 설정해서 사용하기
# 데이터를 가져와서 문자열을 날짜로 다시 변경해두자. df=pd.read_csv('./data/stock-data.csv') df['NewDate']=pd.to_datetime(df['Date']) df.set_index('NewDate', inplace=True) df.drop('Date',axis=1, inplace=True) # df.head() # 날짜 인덱스여서 일부분만 가지고도 인덱싱 가능합니다. # 문자열은 죽었다 깨어나도 안됩니다. df_y=df['2018'] print(df_y.head()) # 범위도 가능하다 # 어떤 컬럼을 할건지까지 할거면 loc 해주자. df_y=df.loc['2018-06-25':'2018-06-30', 'Start':'Low'] print(df_y.head())
- 시계열에서의 결측치 처리
- 결측치를 제거
- 대치법- 대치법(Imputation)
- 누락된 데이터의 이전이나 이후 값으로 채워넣는 것
- 이동 평균으로 데이터를 대입
- 보간법- 보간법
- 인접 데이터를 사용해 누락 데이터를 추정해서 대입
- DF의 interplate 함수를 이용하며, 기본은 선형이다.
- method 속성에서 quadratic을 설정하면 비선형으로도 추정할 수 있다.
- time을 설정한다면 기산을 기준으로 보간합니다.
- limit_direction 매개변수를 이용해서 보간 방향을 설정할 수 있다.# 결측치 처리 time_index=pd.date_range('01-01-2023', periods=5, freq='M') dataframe=pd.DataFrame(index=time_index) dataframe['Sales']=[1.0,2.0,np.nan, np.nan, 5.0] # print(dataframe) # 앞의 데이터로 채우기 # print(datafram.ffill()) # 선형 보간 - 일차식 # print(dataframe.interpolate()) # 비선형 보간 - 다항식 # print(dataframe.interpolate(method='quadratic'))
- 이동시간 윈도우
1. 단순이동 평균
- 현 위치에서 일정한 개수만큼의 이전 데이터와의 통계를 계산
- 이 때 사용되는 함수는 피보나치
- rolling 함수를 이용함
2. 지수 이동 평균(주가 이동 평균)
- 최근의 데이터에 가중치를 두는 방식
- 알파 값을 이용함
-α:1-span(기간)
-(현재값 + (1-α)*현재에서 하나 이전의 값+(1-α)(1-α)*현재에서 두개 이전의 값....)/(1+(1-α)+(1-α)(1-α)+..)
- ewm 함수를 이용함dataframe['Stock_Price']=[1,2,3,4,5] # 단순 이동 평균 print(dataframe.rolling(window=2).mean()) # 지수 이동 평균 print(dataframe.ewm(span=2).mean())
- resampling
- 시계열의 빈도를 변환하는 과정입니다.
- 시계열은 종종 downsampling을 합니다.- downsampling을 하는 상황
- 원본 데이터의 시간 단위가 실용적이지 않은 경우(너무 자주 측정)
- 계절 주기 특성을 파악하기 위한 경우
- 한 데이터를 낮은 빈도로 측정된 다른 데이터와 맞춰주기 위한 경우- upsampling을 하는 상황(권장X)
- 시계열이 불규칙적인 상황
- 입력이 서로 다른 빈도로 샘플링된 상황
- 계절성 데이터
- 일정한 주기를 가지고 변화
- 이를 계절성 시계열 이라고 한다.
- 반복적인 동작을 하지만, 기간이 가변적인 경우는 순환성 시계열 : 주식
pip install opencv-python
import cv2 print(cv2.__vsrsion__)
cv2.namedWindow(윈도우이름:str[, flag:int]) -> None
cv2.imshow(윈도우이름 :str, matrix:ndarray)->None
cv2.destroyAllWindows() -> None
# 모든 값을 200으로 채운 2차원 행렬 생성 image=np.zeros((200,400), np.uint8) image[:]=200 cv2.namedWindow("윈도우 생성") cv2.imshow("윈도우 생성", image) cv2.waitKey(0) cv2.destroyAllWindows()
cv2.line(img, 좌표1, 좌표2, 색상 , 두께, 선모양)
cv2.rectangle(img, 좌표1,좌표2, 색상, 두께, 선모양)
cv2.clipLine(img, 좌표1,좌표2)
cv2.circle(img, center, radius, color, thickness, lineType)
# 흰색 이미지 배열 생성 # 자료형을 np.uint8 로 설정 # 이미지는 0 - 255 사이의 숫자만 이용 # 이미지가 2차원이면 흑백, 3차원이면 컬러 image=np.zeros(shape=(512,512,3), dtype=np.uint8)+255 # 원 만들자 # 두께를 -1로 한다면 채워진 원이 나올 것이다. cv2.circle(image,(image.shape[0]//2, image.shape[1]//2), radius=50, color=(0,0,255), thickness=-1) # RGB -> BGR 헤더쪽에서 거꾸로 되어있거든 # 윈도우에 이미지 출력 cv2.imshow("image",image) #키보드 입력 대기 cv2.waitKey(0) #윈도우 종류 cv2.destroyAllWindows()
cv2.imread(이미지파일 경로, 이미지 옵션)
plt.imshow(array-like or PIL image Data)
cv2.cvtColor
함수를 이용해서 RGB로 변환해서 사용OpenCV에서는 옵션을 정수로 설정합니다.
image=cv2.imread('./data/plane.jpg', cv2.IMREAD_GRAYSCALE) # 이미지 데이터 흑백으로 가져오기 print(image.shape) # C나 C++, python에서는 상수를 정의할 때 이름을 사용한 경우면 # 상수 대신에 값을 직접 입력해도 됩니다. # cv2.IMREAD_GRAYSCALE 대신 0 입력해도 된다. # 하지만 상수 이름을 사용하는 것을 권장합니다. plt.imshow(image, cmap='gray') plt.axis('off') plt.show()
image=cv2.imread('./data/plane.jpg', cv2.IMREAD_COLOR) # 이미지 데이터 흑백으로 가져오기 print(image.shape) # opencv는 rgb로 가져오는게 아닌, bgr로 가져온다. # color는 cmap을 안주면 됩니다. img_rgb=cv2.cvtColor(image, cv2.COLOR_BGR2RGB) plt.imshow(img_rgb) plt.axis('off') plt.show()
cv2.imwrite(파일경로, 이미지 데이터, params=옵션)
image=cv2.imread('./data/plane.jpg', cv2.IMREAD_GRAYSCALE) cv2.imwrite('./data/plane_new.jpg',image)
# 4개의 이미지를 2*2 로 출력 DATA_DIR='./data/' imgBGRs=[] imgBGRs.append(cv2.imread(DATA_DIR+'lena.jpg')) imgBGRs.append(cv2.imread(DATA_DIR+'apple.jpg')) imgBGRs.append(cv2.imread(DATA_DIR+'baboon.jpg')) imgBGRs.append(cv2.imread(DATA_DIR+'orange.jpg')) imgRGBs=[] for i in imgBGRs: imgRGBs.append(cv2.cvtColor(i,cv2.COLOR_BGR2RGB)) # 여러 개의 영역 만들기 fig, ax=plt.subplots(2,2, figsize=(10,10), sharey=True) length=len(imgRGBs) # sharey는 축을 공유하는 것 for i in range(length): ax[i//2][i%2].axis('off') ax[i//2][i%2].imshow(imgRGBs[i],aspect='auto') plt.show()
- 같은 종류라면 리스트를 확인해보자.
cv2.VideoCapture()
## 카메라 캡쳐 # 문자열 출력 함수 def put_string(frame, text, pt, value, color=(120,200,90)): text+=str(value) shade=(pt[0]+2,pt[1]+2) #좌우 상하 2정도 추가 font=cv2.FONT_HERSHEY_SIMPLEX cv2.putText(frame, text,shade, font, 0.7, (0,0,0), 2) #그림자 cv2.putText(frame, text,pt, font, 0.7, color, 2) # 현재 디바이스의 첫번째 카메라 연결 capture=cv2.VideoCapture(0) # 카메라 연결이 안된다면, 종료 if capture.isOpened()==False: raise Exception('카메라 연결 안됨') while True: ret, frame=capture.read() if not ret: break if cv2.waitKey(30)>=0: break exposure=capture.get(cv2.CAP_PROP_EXPOSURE) put_string(frame, "EXPOS: ", (10,40), exposure) title="View Frame From Camera" cv2.imshow(title, frame) capture.release()
# wifi smartphone cap=cv2.VideoCapture('http://IP:port/video') #iphone : video, android : mjpegfeed # frame_size : 카메라 해상도 확인 frame_size=(int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))) print('frame_size= ' ,frame_size) #이거 값이 뭐라도 나와야 함 while True: # 실제 스마트폰 카메라가 촬영하고 있는 영상을 가져오기 retval, frame=cap.read() if not retval: break # 영상을 화면에 출력하기 cv2.imshow('frame',frame) # 키보드 대기하기 key=cv2.waitKey(25) if key==27: #27이 esc이다. # esc를 누르면 종료한다. break if cap.isOpened(): cap.release() cv2.destroyAllWindows()
(32x32), (64x64), (96x96), (128x128), (256x256)
이다.img=cv2.imread('./data/lena.jpg',cv2.IMREAD_GRAYSCALE) # print('img shape', img.shape) # 2차원 이미지를 1차원으로 변경해주자. - flatten img=img.flatten() # 1차원으로 잘 변경되었다. # print('img shape', img.shape) # 이걸 또 3차원으로 바꿔? # -1은 나머지를 "전부" 사용한다는 의미입니다. # 262144/512/512가 첫 번째 차원입니다. # 두개만 계산하고 나머지 그냥 넣어서 좀 더 편리하게 함 img=img.reshape(-1,512,512) # 첫 번째 차원은 1이 됩니다. print('img shape',img.shape)
img=cv2.imread('./data/plane_256x256.jpg', cv2.IMREAD_GRAYSCALE) img=cv2.resize(img, (64,64)) #좀 깨져보인다. plt.imshow(img, cmap='gray') plt.axis('off') plt.show()
img=cv2.imread('./data/lena.jpg', cv2.IMREAD_GRAYSCALE) img[100,200]=0 img[100:400, 200:300]=0 plt.imshow(img, cmap='gray') plt.axis('off') plt.show() # 이미지의 특정 부분을 선택하는 것 : ROI # 이미지 전처리의 핵심 중 하나가 #ROI 부분을 다른 부분과 확연하게 구분되도록 하는 것
img=cv2.imread('./data/lena.jpg') img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB) print(img.shape) # shape : 가로, 세로, 색상 채널 # 색상채널 접근때리기 # 0, 1, 2 있는데 0 이 R인걸로 보아 RGB 형태네 img[100:400,200:300, 0]=0 # R값이 빠지니까 CYAN으로 변한 것을 볼 수 있다. plt.imshow(img) plt.axis('off') plt.show()
selectROI(윈도우이름, 이미지[, showCrosshair[,fromCenter])->retval
img=cv2.imread('./data/lena.jpg') img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB) roi=cv2.selectROI(img) print('roi : ', roi) # 선택 영역만 추출 img=img[roi[1]:roi[1]+roi[3], roi[0]:roi[0]+roi[2]] cv.imshow("IMG",img) cv2.waitKey() cv2.destroyAllWindows()
copy
함수나 zeros
같은 함수를 이용해서 빈 배열을 만들고 데이터를 복사함 cv2.split(이미지데이터)
cv2.merge([채널 데이터 나열])
img=cv2.imread('./data/lena.jpg') # img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 채널 분할 b, g, r=cv2.split(img) # 채널 병합 img=cv2.merge([b,g,r]) cv2.imshow("IMG",img) cv2.waitKey() cv2.destroyAllWindows()
cvtColor(이미지, 변환코드[,dst])->dst
cv2.COLOR_BGR2GRAY cv2.COLOR_GRAY2BGR cv2.COLOR_BGR2HSV cv2.COLOR_HSV2BGR
- COLOR가 있는 데이터를 gray로 변환하는 경우가 종종 있는데, 이 경우는 특정 영역과 다른 영역의 구분을 뚜렷하게 하고자 하는 경우에 사용합니다.
cv2.flip(이미지, flipCode)->dst
cv2.transpose(src)->dst
img=cv2.imread('./data/flip_test.jpg') # flip_img=cv2.flip(img,-1) # plt.imshow(flip_img) # transpose : 행 열 전치하기 # transpose_img=cv2.transpose(img) # plt.imshow(transpose_img) # 회전 : rotate rotate_img=cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE) rotate_img=cv2.rotate(img, cv2.ROTATE_180) rotate_img=cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE) plt.imshow(rotate_img) plt.axis('off') plt.show()
scale, angle, translate
cv2.getRotationMatrix2D(center, angle, scale)->Matrix
함수를 이용함Matrix[:,2]+=(tx,tx)
를 이용하면, translate도 구현합니다.src=cv2.imread('./data/lena.jpg') src=cv2.cvtColor(src, cv2.COLOR_BGR2RGB) rows,cols,channels=src.shape # 중앙을 기준으로 45도 회전, 0.5배 축소 이미지 M1=cv2.getRotationMatrix2D((rows/2,cols/2), 45, 0.5) src=cv2.warpAffine(src,M1,(rows,cols)) plt.imshow(src) plt.axis('off') plt.show()
- 실제로 회전을 가장 많이 사용하긴 한다.