여러데이터를 보게되면 시간의 형식이 달라서 

곤란한 경우가 있다 예를 들어 A데이터는 자정을 15일 00시라고 하고 B데이터는 14일 24시라고 하는 경우이다.

B의 경우에는 판다스의 데이터타임이 시간을 인식하지 못하여 타임으로 변환하지 못한다.

 

time00 = '2022021500'
pd.to_datetime(time00, format='%Y%m%d%H')
Timestamp('2022-02-15 00:00:00')
time24 = '2022021424'
pd.to_datetime(time, format='%Y%m%d%H')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~\anaconda3\lib\site-packages\pandas\core\tools\datetimes.py in _to_datetime_with_format(arg, orig_arg, name, tz, fmt, exact, errors, infer_datetime_format)
    508         try:
--> 509             values, tz = conversion.datetime_to_datetime64(arg)
    510             dta = DatetimeArray(values, dtype=tz_to_dtype(tz))

 

보통의 날은 문자열의 처리로 가능하겠지만 월이바뀌는 01/31/24과 02/01/00같은 경우에는 곤란할 것이다.

 

그렇기 때문에 마지막 24라는 문자열을 00으로 대체후에 타임델타를 이용하여 하루 이후로 가는  방식이 이상적인 것 같다

 

from datetime import datetime, timedelta

def zerofrom24(datetime, _format):
    datetime = str(datetime)
    try:
        return pd.to_datetime(datetime, format = _format)
    except:
        datetime = datetime[:-2] + '00'
        return pd.to_datetime(datetime, format = _format)+ timedelta(days=1)
    
print(zerofrom24('2022021424','%Y%m%d%H'))
print(zerofrom24('2022021500','%Y%m%d%H'))
2022-02-15 00:00:00
2022-02-15 00:00:00
print(ex)
print(ex.map(lambda x : zerofrom24(x,'%Y%m%d%H')))
20    2021010121
21    2021010122
22    2021010123
23    2021010124
Name: 측정일시, dtype: int64
20   2021-01-01 21:00:00
21   2021-01-01 22:00:00
22   2021-01-01 23:00:00
23   2021-01-02 00:00:00
Name: 측정일시, dtype: datetime64[ns]

이렇게 모든 것을 00으로 맞춘후에 조인하면된다

1. 생성

pd.to_datetime

from datetime import datetime 


date_list = ['1997-07-22',datetime(1998,11,9),'22nd of jul, 1999']
date_series = pd.Series(date_list)


print(date_list)
print(date_series)

print(pd.to_datetime(date_list))
print(pd.to_datetime(date_series))

 

['1997-07-22', datetime.datetime(1998, 11, 9, 0, 0), '22nd of jul, 1999']
0             1997-07-22
1    1998-11-09 00:00:00
2      22nd of jul, 1999
dtype: object
DatetimeIndex(['1997-07-22', '1998-11-09', '1999-07-22'], dtype='datetime64[ns]', freq=None)
0   1997-07-22
1   1998-11-09
2   1999-07-22
dtype: datetime64[ns]

여러가지의 시간 형식을 자동으로 datetime형식으로 바꾸어준다 리스트의 경우 인덱스 객ㄹ체로 시리즈의 경우 각 원소가 데이트 타임인 시리즈로 리턴해준다

 

기본적인 포맷은 자동으로 처리해주지만

pd.to_datetime('2022:07:22:00:00')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~\anaconda3\lib\site-packages\pandas\core\arrays\datetimes.py in objects_to_datetime64ns(data, dayfirst, yearfirst, utc, errors, require_iso8601, allow_object, allow_mixed)
   2186         try:
-> 2187             values, tz_parsed = conversion.datetime_to_datetime64(data.ravel("K"))
   2188             # If tzaware, these values represent unix timestamps, so we

이렇게 기본적인 포맷이 아닌경우에는 오류가 일어난다 이럴경우에는 포맷을 직접 지정해주면된다.

 

pd.to_datetime('22:7:22:00:00:00', format='%y:%m:%d:%H:%M:%S')
Timestamp('2022-07-22 00:00:00')

format = '문자열'로 지정해주면 성공적으로 된다.

같은 위치에 원하는 형식을 넣어주면된다.

 

형식 포맷
네자리 연도 (2020) %Y
두자리 연도 (20) %y
%m
날짜 %d
%H
%M
%S

 

 

pd.date_range

 

print(pd.date_range('2022-01-01', periods =7, freq='2H'))
print(pd.date_range('2022-01-01', periods =7, freq='2H'))
print(pd.date_range('2022-01-01', periods =7, freq='D'))
print(pd.date_range('2022-01-01', periods =7, freq='M'))
print(pd.date_range('2022-01-01', periods =7, freq='Y'))
DatetimeIndex(['2022-01-01 00:00:00', '2022-01-01 02:00:00',
               '2022-01-01 04:00:00', '2022-01-01 06:00:00',
               '2022-01-01 08:00:00', '2022-01-01 10:00:00',
               '2022-01-01 12:00:00'],
              dtype='datetime64[ns]', freq='2H')
DatetimeIndex(['2022-01-01', '2022-01-02', '2022-01-03', '2022-01-04',
               '2022-01-05', '2022-01-06', '2022-01-07'],
              dtype='datetime64[ns]', freq='D')
DatetimeIndex(['2022-01-31', '2022-02-28', '2022-03-31', '2022-04-30',
               '2022-05-31', '2022-06-30', '2022-07-31'],
              dtype='datetime64[ns]', freq='M')
DatetimeIndex(['2022-12-31', '2023-12-31', '2024-12-31', '2025-12-31',
               '2026-12-31', '2027-12-31', '2028-12-31'],
              dtype='datetime64[ns]', freq='A-DEC')

원하는 stride를 기준으러 생성가능하다

pd.date_range(시작날짜, 끝날짜, freq = 'stride', periods = (정수, 이거 사용시 끝날짜 x))

 

2. 연산

from datetime import timedelta

dt_Series = pd.to_datetime(date_series)
print(dt_Series)
print('-'*30)
print('지금시간 : ', datetime.today())
print('-'*30)
print(dt_Series - datetime.today())
print('-'*30)
print(dt_Series - datetime(1998,11,9))
print('-'*30)
print(dt_Series - datetime(1998,11,9) > timedelta(days=1))
print('-'*30)
print(dt_Series + timedelta(days=1))
0   1997-07-22
1   1998-11-09
2   1999-07-22
dtype: datetime64[ns]
------------------------------
지금시간 :  2022-02-14 15:35:32.845328
------------------------------
0   -8974 days +08:24:27.154672
1   -8499 days +08:24:27.154672
2   -8244 days +08:24:27.154672
dtype: timedelta64[ns]
------------------------------
0   -475 days
1      0 days
2    255 days
dtype: timedelta64[ns]
------------------------------
0    False
1    False
2     True
dtype: bool
------------------------------
0   1997-07-23
1   1998-11-10
2   1999-07-23
dtype: datetime64[ns]

시간끼리의 연산이 가능하다.

 

시간의 스칼라를 timedelta로 더할수도 

한 시점과 한 시점을 비교, 연산할 수도 있다.

데이터 출처 :

https://www.data.go.kr/data/15025602/fileData.do

 

 

import pandas as pd
import numpy as np

df = pd.read_csv('C:\\Users\\user\\Desktop\\티스토리데이터\\수원도시공사_실내공기질 측정 정보_20201211.csv', encoding = 'euc-kr')
df = df[['미세먼지(㎍/㎡)','이산화탄소(ppm)','포름알데히드(㎍/㎡)','일산화탄소(ppm)']]

print(df.shape)

for i in range(5):
    df.iloc[np.random.randint(df.shape[0]),np.random.randint(1,df.shape[1])] = np.nan

print(df.isna().sum())

df.columns = ['미세먼지','이산화탄소','포름알데히드','일산화탄소']
display(df)
(7, 4)
미세먼지(㎍/㎡)      0
이산화탄소(ppm)     1
포름알데히드(㎍/㎡)    2
일산화탄소(ppm)     2
dtype: int64

 


미세먼지 이산화탄소 포름알데히드 일산화탄소
0 49.8 513.0 3.838 NaN
1 33.0 476.5 2.556 3.60
2 40.5 460.0 6.647 3.10
3 54.4 498.7 NaN 4.97
4 41.5 473.0 6.796 2.90
5 56.4 491.5 NaN 3.25
6 63.1 NaN 4.873 NaN

데이터를 가져와 미세먼지열을 제외한 컬럼에 임의로 nan값을 발생시켰다.

 

 

1. dropna()

nan을 포함하는 행을 모두 삭제하는 방법

df.dropna()

미세먼지 이산화탄소 포름알데히드 일산화탄소
1 33.0 476.5 2.556 3.6
2 40.5 460.0 6.647 3.1
4 41.5 473.0 6.796 2.9

2. fillna()

원하는 값으로 채우는 방법

display(df.fillna(0))

미세먼지 이산화탄소 포름알데히드 일산화탄소
0 49.8 513.0 3.838 0.00
1 33.0 476.5 2.556 3.60
2 40.5 460.0 6.647 3.10
3 54.4 498.7 0.000 4.97
4 41.5 473.0 6.796 2.90
5 56.4 491.5 0.000 3.25
6 63.1 0.0 4.873 0.00

0으로 채워짐

 

print(df.mean())
display(df.fillna(df.mean()))
미세먼지       48.385714
이산화탄소     485.450000
포름알데히드      4.942000
일산화탄소       3.564000
dtype: float64

미세먼지 이산화탄소 포름알데히드 일산화탄소
0 49.8 513.00 3.838 3.564
1 33.0 476.50 2.556 3.600
2 40.5 460.00 6.647 3.100
3 54.4 498.70 4.942 4.970
4 41.5 473.00 6.796 2.900
5 56.4 491.50 4.942 3.250
6 63.1 485.45 4.873 3.564

각 열의 평균으로 대치가 된다.

같은 방법으로 중앙값, 사분위 수 등의 스칼라로 대체가능하다.

 

df.fillna(method='ffill')

미세먼지 이산화탄소 포름알데히드 일산화탄소
0 49.8 513.0 3.838 NaN
1 33.0 476.5 2.556 3.60
2 40.5 460.0 6.647 3.10
3 54.4 498.7 6.647 4.97
4 41.5 473.0 6.796 2.90
5 56.4 491.5 6.796 3.25
6 63.1 491.5 4.873 3.25

각 컬럼의 앞값을 복사한다. 

method를 'bfill'로 넣는다면 뒷값을 복사한다. 일산화탄소 컬럼의 첫 원소는 앞원소가 존재하지않아 nan을 유지한다.

 

3.interpolate()

 

df.interpolate(method='values')

미세먼지 이산화탄소 포름알데히드 일산화탄소
0 49.8 513.0 3.8380 NaN
1 33.0 476.5 2.5560 3.60
2 40.5 460.0 6.6470 3.10
3 54.4 498.7 6.7215 4.97
4 41.5 473.0 6.7960 2.90
5 56.4 491.5 5.8345 3.25
6 63.1 491.5 4.8730 3.25

nan부분을 앞뒤 원소의 선형식으로 보간함

 

4. 다른 값을 통한 예측

 

from sklearn import linear_model 
reg = linear_model.LinearRegression() 

df_dn = df[['미세먼지','이산화탄소']].dropna()
reg.fit(df_dn['미세먼지'].values.reshape(-1,1), df_dn['이산화탄소'])
dust_list = df['미세먼지'].loc[df['이산화탄소'].isna()].tolist()

df['이산화탄소'].loc[df['이산화탄소'].isna()] = list(map(lambda x : reg.predict(np.array(x).reshape(-1,1)), dust_list))

미세먼지 이산화탄소 포름알데히드 일산화탄소
0 49.8 513.000000 3.838 NaN
1 33.0 476.500000 2.556 3.60
2 40.5 460.000000 6.647 3.10
3 54.4 498.700000 NaN 4.97
4 41.5 473.000000 6.796 2.90
5 56.4 491.500000 NaN 3.25
6 63.1 510.048021 4.873 NaN

미세먼지와 이산화탄소 사이의 단순선형회귀 분석을 통해 

이산화탄소의 값을 예측하여 nan값을 채운것

데이터 출처:

https://www.data.go.kr/data/15013192/standard.do

 

전국금연구역표준데이터

금연구역 정보(금연구역 지역, 면적, 위반과태료 등)를 제공합니다. 공공데이터 개방 표준데이터 속성정보(표현형식/단위 등)는 [공공데이터 개방 표준]고시를 참고하시기 바랍니다.(정보공유>

www.data.go.kr

 

 

위 링크의 데이터 목록처럼 데이터 컬럼 형식은 같지만 방대한 데이터의 양 때문에 데이터를 끊어서 제공하는 경우가 있다.

일일이 데이터를 읽고 concat하기에는 시간이 오래 걸리기에 for문과 os, pandas 모듈을 사용하여 concat하는 방법이다.

 

1. os 모듈로 작업위치 확인 및 변경

 

import os
import pandas as pd

os.getcwd()
'C:\\Users\\user'

os.getcwd()는 현재 작업중인 파이썬 폴더를 알려준다.

 

os.chdir("C:\\Users\\user\\Desktop\\티스토리데이터\\os")
os.getcwd()
'C:\\Users\\user\\Desktop\\티스토리데이터\\os'

os.chdir()를 활용하면 폴더를 옮길 수 있다. 

 

폴더의 경로는 폴더내의 빈공간을 마우스 우클릭 후 속성탭에 들어가면 위치를 확인 가능하다.

 

그리고 주피터 노트북내에서 원하는 셀을 누른뒤에 esc를 누르고 f를 누르면 일괄바꾸기 기능이 작동되는데 \를  \\로 바꿔주면 파이썬에서 인식하는 경로의 형식으로 바꾸는게 손쉽게 가능하다.

print(os.listdir())
['chim_df.xlsx', 'corr.csv', 'tb_hb_ind_egnin_m.csv', 'test.csv', 'test_.csv', 'test_cnt.csv', '경기도_가평군_금연구역_20211012_1634033497993_29131.csv', '경기도_고양시_금연구역_20210920_1634617775511_649377.csv', '경기도_남양주시_금연구역_20210930_1634027480812_2270079.csv', '경기도_포천시_금연구역_20210930_1634790042474_958431.csv', '계산을해보자.csv', '상권분석_final.twbx', '성연령별매출 추출_Extract.csv', '청년상권 클러스터링.ipynb']

os.listdir() 을 활용하면 현재 폴더안에 있는 파일들의 이름을 불러와준다.

 

여기서 우리가 가져와야할 데이터는 

경기도_xxx_금연구역_xxxx.csv 

이런 형식의 데이터만 불러와 concat하고자 한다.

 

print(os.listdir())
csv_list = list(filter(lambda x : x.split('.')[-1] == 'csv', os.listdir()))
print(csv_list)
csv_list2 = list(filter(lambda x : '금연구역'in x, csv_list))
print(csv_list2)
['chim_df.xlsx', 'corr.csv', 'tb_hb_ind_egnin_m.csv', 'test.csv', 'test_.csv', 'test_cnt.csv', '경기도_가평군_금연구역_20211012_1634033497993_29131.csv', '경기도_고양시_금연구역_20210920_1634617775511_649377.csv', '경기도_남양주시_금연구역_20210930_1634027480812_2270079.csv', '경기도_포천시_금연구역_20210930_1634790042474_958431.csv', '계산을해보자.csv', '상권분석_final.twbx', '성연령별매출 추출_Extract.csv', '청년상권 클러스터링.ipynb']
['corr.csv', 'tb_hb_ind_egnin_m.csv', 'test.csv', 'test_.csv', 'test_cnt.csv', '경기도_가평군_금연구역_20211012_1634033497993_29131.csv', '경기도_고양시_금연구역_20210920_1634617775511_649377.csv', '경기도_남양주시_금연구역_20210930_1634027480812_2270079.csv', '경기도_포천시_금연구역_20210930_1634790042474_958431.csv', '계산을해보자.csv', '성연령별매출 추출_Extract.csv']
['경기도_가평군_금연구역_20211012_1634033497993_29131.csv', '경기도_고양시_금연구역_20210920_1634617775511_649377.csv', '경기도_남양주시_금연구역_20210930_1634027480812_2270079.csv', '경기도_포천시_금연구역_20210930_1634790042474_958431.csv']

이렇게 파이썬의 내장함수 filter를 활용하면 리스트 중 조건에 만족하는 리스트만을 생성할 수 있다.

https://gwoolab.tistory.com/13

 

[ python 기초 ] lambda, map, filter

lambda 함수를 한줄에 정의하고 사용만 한다.코드의 간결함 메모리의 절약 람다 함수는 정의와 동시에 사용할 수 있음 lambda 매개변수 : 리턴값 print((lambda x : x**2)(2)) 4 제곱을 해주는 함수를 정의하

gwoolab.tistory.com

 

이렇게 타겟하는 파일만을 확인하고 포문으로 빈데이터 프레임에 하나씩 쌀으면 된다

 

df = pd.DataFrame()

for file in csv_list2:
    tmp_df = pd.read_csv(file, encoding = 'euc-kr')
    print(tmp_df.shape)
    df = pd.concat([df,tmp_df])
    print(df.shape)
(131, 15)
(131, 15)
(2572, 15)
(2703, 15)
(10496, 15)
(13199, 15)
(3393, 15)
(16592, 15)

데이터 들이 df라는 데이터에 차례로 쌓이는 것을 확인할 수 있다.

 

 

 

 

import pandas as pd
df = pd.read_csv('C:\\Users\\user\\Desktop\\티스토리데이터\\수원도시공사_실내공기질 측정 정보_20201211.csv', encoding = 'euc-kr')
df.head(3)

주차장명 주소 규모(㎡) 미세먼지(㎍/㎡) 이산화탄소(ppm) 포름알데히드(㎍/㎡) 일산화탄소(ppm) 오존(ppm) 측정결과 데이터기준일
0 교동공영주차장 팔달구 향교로 140(교동) 9165.68 49.8 513.0 3.838 4.00 NaN 양호 2020/12/11
1 권선지하공영주차장 권선구 세지로 82번길 15-3(권선동) 2073.96 33.0 476.5 2.556 3.60 NaN 양호 2020/12/11
2 매봉공영주차장 영통구 동탄원천로 1109번길 61(매탄동) 4682.43 40.5 460.0 6.647 3.10 NaN 양호 2020/12/11

데이터 출처 :

https://www.data.go.kr/data/15025602/fileData.do

 

수원도시공사_실내공기질 측정 정보_20201211

수원도시공사 실내공기질 측정 정보 (주차장명, 주소, 규모, 미세먼지, 이산화탄소, 포름알데히드, 일산화탄소, 오존) 데이터를 제공합니다.

www.data.go.kr

 

 

1. columns에 리스트 넣기

df.columns = ['a', 'b', 'c', 'd', 'e', 'f',
       'g', 'h', 'i', 'j' ]
df.head(3)

a b c d e f g h i j
0 교동공영주차장 팔달구 향교로 140(교동) 9165.68 49.8 513.0 3.838 4.0 NaN 양호 2020/12/11
1 권선지하공영주차장 권선구 세지로 82번길 15-3(권선동) 2073.96 33.0 476.5 2.556 3.6 NaN 양호 2020/12/11
2 매봉공영주차장 영통구 동탄원천로 1109번길 61(매탄동) 4682.43 40.5 460.0 6.647 3.1 NaN 양호 2020/12/11

컬럼명이 알파벳으로 바뀜

단. 이경우 입력되는 리스트의 길이가 원데이터프레임의 길이와 일치 하지 않을시 에러발생

 

2. pandas의 rename 활용

 

원하는 컬럼만 이름 변경가능

df.rename(columns = {'c':'C','h':'H'}, inplace =True)
df.head(1)

a b C d e f g H i j
0 교동공영주차장 팔달구 향교로 140(교동) 9165.68 49.8 513.0 3.838 4.0 NaN 양호 2020/12/11

c와 h만 대문자로 변환

 

df.rename({'a':'A','b':'B','e':'E' }, axis = 1, inplace =True)
df.head(1)


A
B C d E f g H i j
0 교동공영주차장 팔달구 향교로 140(교동) 9165.68 49.8 513.0 3.838 4.0 NaN 양호 2020/12/11

axis를 활용해도 가능

 

이 형식을 포문을 활용해서 간단하게 모두 대문자로 바꿀 수 있음

 

for col in df.columns:
    df.rename({col:col.upper()}, axis = 1, inplace =True)
df.head(1)

A B C d E f g H i j
0 교동공영주차장 팔달구 향교로 140(교동) 9165.68 49.8 513.0 3.838 4.0 NaN 양호 2020/12/11

rename(axis) 를 활용한 방법은 인덱스에서도 동일적용가능

 

A 컬럼을 인덱스로 설정후 원하는 인덱스만 이름바꾸기

df.set_index('A', drop = True, inplace =True)
df.rename({'교동공영주차장':'교동'}, inplace = True )
df.head()

B C D E F G H I J
A








교동 팔달구 향교로 140(교동) 9165.68 49.8 513.0 3.838 4.00 NaN 양호 2020/12/11
권선지하공영주차장 권선구 세지로 82번길 15-3(권선동) 2073.96 33.0 476.5 2.556 3.60 NaN 양호 2020/12/11
매봉공영주차장 영통구 동탄원천로 1109번길 61(매탄동) 4682.43 40.5 460.0 6.647 3.10 NaN 양호 2020/12/11
영통공영주차장 영통구 봉영로 1598(영통동) 10974.16 54.4 498.7 3.639 4.97 NaN 양호 2020/12/11
영화동공영주차장 장안구 수성로 382번길 24(영화동) 5365.87 41.5 473.0 6.796 2.90 NaN 양호 2020/12/11
for idx in df.index:
    df.rename({idx:idx.replace('공영주차장','')}, inplace = True )
df.head()


B
C D E F G H I J
A








교동 팔달구 향교로 140(교동) 9165.68 49.8 513.0 3.838 4.00 NaN 양호 2020/12/11
권선지하 권선구 세지로 82번길 15-3(권선동) 2073.96 33.0 476.5 2.556 3.60 NaN 양호 2020/12/11
매봉 영통구 동탄원천로 1109번길 61(매탄동) 4682.43 40.5 460.0 6.647 3.10 NaN 양호 2020/12/11
영통 영통구 봉영로 1598(영통동) 10974.16 54.4 498.7 3.639 4.97 NaN 양호 2020/12/11
영화동 장안구 수성로 382번길 24(영화동) 5365.87 41.5 473.0 6.796 2.90 NaN 양호 2020/12/11

인덱스에서 공영주차장이라는 말을 제거하고 인덱스를 생성할 수 있다

데이터 타입변경

lf_bus = pd.read_csv('./저상버스.csv')
display(lf_bus.head())
lf_bus.info()

노선번호 인가대수 저상대수 보유율 배차간격 저상버스간격 차량count
0 100 32 32 1.0 8 8 135
1 742 31 24 1.0 8 10 105
2 2312 21 3 0.0 8 56 19
3 4312 29 14 0.0 8 17 65
4 5634 15 11 1.0 8 11 99
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 294 entries, 0 to 293
Data columns (total 7 columns):
 #   Column   Non-Null Count  Dtype  
---  ------   --------------  -----  
 0   노선번호     294 non-null    object 
 1   인가대수     294 non-null    int64  
 2   저상대수     294 non-null    int64  
 3   보유율      293 non-null    float64
 4   배차간격     294 non-null    int64  
 5   저상버스간격   294 non-null    object 
 6   차량count  294 non-null    object 
dtypes: float64(1), int64(3), object(3)
memory usage: 16.2+ KB

데이터 프레임을 확인하면 모든 데이터의 값이 숫자형태로 보이지만 사실은 오브젝트 형태인 녀석들이 있다 이러면 숫자 연산이 불가능 하기때문에 숫자형태로 형변환이 필요하다.

 

print(lf_bus['저상버스간격'])
print(lf_bus['저상버스간격'].astype('int'))
0       8
1      10
2      56
3      17
4      11
       ..
288     8
289     8
290    11
291     8
292     8
Name: 저상버스간격, Length: 293, dtype: object
0       8
1      10
2      56
3      17
4      11
       ..
288     8
289     8
290    11
291     8
292     8
Name: 저상버스간격, Length: 293, dtype: int32

이렇게 바꾼다 . 이것을 포문을 이용해서 바꾸고싶은 열만 바꾸면

int_cols = lf_bus.columns.tolist()
int_cols.remove('노선번호')
print(int_cols)

for col in int_cols:
    lf_bus[col] = lf_bus[col].astype('int')

lf_bus.info()
['인가대수', '저상대수', '보유율', '배차간격', '저상버스간격', '차량count']
<class 'pandas.core.frame.DataFrame'>
Int64Index: 293 entries, 0 to 292
Data columns (total 7 columns):
 #   Column   Non-Null Count  Dtype 
---  ------   --------------  ----- 
 0   노선번호     293 non-null    object
 1   인가대수     293 non-null    int32 
 2   저상대수     293 non-null    int32 
 3   보유율      293 non-null    int32 
 4   배차간격     293 non-null    int32 
 5   저상버스간격   293 non-null    int32 
 6   차량count  293 non-null    int32 
dtypes: int32(6), object(1)
memory usage: 11.4+ KB

내가 지정한 컬럼을 int32타입으로 바꿀 수 있다.

 

데이터 범주화

count= lf_bus['차량count']
lf_bus['범주'] = pd.cut(count,4, include_lowest= False)
print(lf_bus['범주'])
print('*'*30)
print(count.describe().iloc[3:])
print('*'*30)
lf_bus['범주'] = pd.cut(count,count.describe().iloc[3:], include_lowest= True)
print(lf_bus['범주'])
print('*'*30)
lf_bus['범주'] = pd.cut(count,count.describe().iloc[3:], labels = False, include_lowest= False)
print(lf_bus['범주'])
print('*'*30)
lf_bus['범주'] = pd.cut(count,count.describe().iloc[3:], labels = ['a','b','c','d'], include_lowest= False)
print(lf_bus['범주'])
0      (103.0, 135.0]
1      (103.0, 135.0]
2       (6.872, 39.0]
3        (39.0, 71.0]
4       (71.0, 103.0]
            ...      
288    (103.0, 135.0]
289    (103.0, 135.0]
290     (71.0, 103.0]
291    (103.0, 135.0]
292    (103.0, 135.0]
Name: 범주, Length: 293, dtype: category
Categories (4, interval[float64, right]): [(6.872, 39.0] < (39.0, 71.0] < (71.0, 103.0] < (103.0, 135.0]]
******************************
min      7.0
25%     68.0
50%     92.0
75%    122.0
max    135.0
Name: 차량count, dtype: float64
******************************
0      (122.0, 135.0]
1       (92.0, 122.0]
2       (6.999, 68.0]
3       (6.999, 68.0]
4       (92.0, 122.0]
            ...      
288    (122.0, 135.0]
289    (122.0, 135.0]
290     (92.0, 122.0]
291    (122.0, 135.0]
292    (122.0, 135.0]
Name: 범주, Length: 293, dtype: category
Categories (4, interval[float64, right]): [(6.999, 68.0] < (68.0, 92.0] < (92.0, 122.0] < (122.0, 135.0]]
******************************
0      3.0
1      2.0
2      0.0
3      0.0
4      2.0
      ... 
288    3.0
289    3.0
290    2.0
291    3.0
292    3.0
Name: 범주, Length: 293, dtype: float64
******************************
0      d
1      c
2      a
3      a
4      c
      ..
288    d
289    d
290    c
291    d
292    d
Name: 범주, Length: 293, dtype: category
Categories (4, object): ['a' < 'b' < 'c' < 'd']

pd.cut 함수로 데이터의 범주화가 가능하다.

원래는 if, else문을 활용해서 함수정의 후 map으로 각각 적용했는데

pd.cut을 이용하면 간단하게 범주화가 가능하다. 데이터타입은 labels = False가 아니라면 

기본적으로 카테고리 데이터이다.

라벨을 지정하면 카테고리 명을 설정가능하다.

데이터를 자르는 경계를 설정하지않으면 등간격으로 잘라준다.

 

include_lowest= True 를 선택시 왼쪽 간격을 포함, False시 미포함

 

( 는 <를 ] =<를 의미

pandas

import pandas as pd

 

- 빅데이터 연산의 기초

- 데이터 구조를 정의

- numpy와 같은 타 모듈과의 전환이 용이

- pd라고 alias를 정의해 빠르게 사용 다른 alias를 지정해도 사용에는 무방하나 pd로 칭하는게 암묵적인 룰

 

 

시리즈란

- 파이썬기본 데이터유형인 딕셔너리와 유사한형태

- index : value 형태로 이루어진 데이터 

- 집계연산의 편의, 인덱싱의 편의

- 시리즈를 결합하면 데이터프레임이됨

- 데이터프레임에서 그룹 연산시 산출물이 시리즈로 제공되기 때문에 알고있어야 도움

 

생성

series1 = pd.Series({'국어':100, '수학':90, '영어':80})
series2 = pd.Series([100,20,45,90,100,87,45], index = ['k','e','a','b','f','c','d'])
series3 = pd.Series([100,20,45,90,100,87,45])
print(series1)
print('-'*30)
print(series2)
print('-'*30)
print(series3)
국어    100
수학     90
영어     80
dtype: int64
------------------------------
k    100
e     20
a     45
b     90
f    100
c     87
d     45
dtype: int64
------------------------------
0    100
1     20
2     45
3     90
4    100
5     87
6     45
dtype: int64

value와 인덱스를 지정하여 생성가능 인덱스를 지정하지 않을시 0에서 시작하는 정수로 순서대로 임의의 인덱스 부여

딕셔너리와 유사한 형태이기때문에 딕셔너리로 생성도 가능

 

 

인덱싱과 슬라이싱

두가지 방법으로 가능 해당하는 인덱스로 / 위치로

 

print(series2)
print('-'*30)

# 인덱스로 인덱싱 혹은 슬라이싱
print(series2['k'])
print('-'*30)
print(series2['k':'a'])
print('-'*30)

# 위치로 
print(series2.iloc[1])
print('-'*30)
print(series2.iloc[:1])
k    100
e     20
a     45
b     90
f    100
c     87
d     45
dtype: int64
------------------------------
100
------------------------------
k    100
e     20
a     45
dtype: int64
------------------------------
20
------------------------------
k    100
dtype: int64

인덱싱시 해당하는 인덱스에 속한 밸류를 반환한다.

슬라이싱시 해당하는 범위의 시리즈를 반환한다.

 

iloc을 이용할시 위치에 따라 인덱싱과 슬라이싱이 가능하다 1번째 값은(파이썬은 0부터시작) 20이기에 20을 반환

iloc[:1] 은 1번째 전까지의 녀석을 시리즈로 반환한다.

 

series2[['a','b','d']]
a    45
b    90
d    45
dtype: int64

이렇게 원하는녀석들만 볼 수도있다.

 

불리언 인덱싱

print((90>=series2) & (series2>50))
print('-'*30)
print(series2.loc[(90>=series2) & (series2>50)])
k    False
e    False
a    False
b     True
f    False
c     True
d    False
dtype: bool
------------------------------
b    90
c    87
dtype: int64

시리즈의 밸류에 관하여 불리언 연산이 가능하고 

그 불리언의 트루에 해당하는값만을 슬라이싱 가능하다.

 

print(series2.loc[(series2.index > 'b').tolist()])
k    100
e     20
f    100
c     87
d     45
dtype: int64

이런식으로 한다면 인덱스의 불리언 연산도 가능하다.

따로 기능이있는지는 잘모르겠다

 

시리즈 정렬

print(series2.sort_values())
print('-'*30)
print(series2.sort_values(ascending = False))
e     20
a     45
d     45
c     87
b     90
k    100
f    100
dtype: int64
------------------------------
k    100
f    100
b     90
c     87
a     45
d     45
e     20
dtype: int64

시리즈의 값을 기준으로 정렬을 할 수 있다. ascending을 False로 설정하면 내림차순으로 정렬된다.

print(series2.sort_index())
print('-'*30)
print(series2.sort_index(ascending = False))
a     45
b     90
c     87
d     45
e     20
f    100
k    100
dtype: int64
------------------------------
k    100
f    100
e     20
d     45
c     87
b     90
a     45
dtype: int64

인덱스를 기준으로도 거의 동일하게 정렬이 가능하다.

 

갯수세기

series2.value_counts()
100    2
45     2
20     1
90     1
87     1
dtype: int64

밸류의 갯수세기도 가능하다

인덱스는 보통 유일한 값을 가지기때문에 인덱스에 대한 물음은 가지지않았다.

 

간단한 연산

print(series2.mean())
print(series2.max())
print(series2.min())
print(series2.median())
69.57142857142857
100
20
87.0

 

+ Recent posts