---------------------Python
df = pd.read_csv(DriveUrl)
type(df)
-> pandas.core.frame.Dataframe : 엑셀같은 폼을 Dataframe이라고 함
#read_csv로 데이터를 로드할때 컬럼이 한글이면 read_csv(Url,encoding = 'euc-kr')처럼 encoding = 'euc-kr' 포함
df.head()
: 상위 5개의 행이 나옴
#python에서 숫자는 0부터 시작
print(df.shape)
: 데이터 행과 열의 갯수 출력
df.columns
: 전체 칼럼을 보여줌
#6번째 칼럼을 출력할때 : df.columns[5] -> python은 처음 숫자가 0이기 때문에 6번째면 5를 넣어야함
df.iloc[: ,5].dtype
: 6번째 컬럼의 데이터 타입을 확인하기
#iloc[행,열] -> 여기서 :는 "모든"을 말함 , 이제 여기서 .dtype은 데이터 타입을 확인하는 명령어
#6번째 컬럼의 3번쨰 값은? df.iloc[2:5] 이다.
df.index
:데이터 셋의 인덱스 구성을 확인
-> RangeIndex(start=0, stop=51490 , step =1)
: 이것은 인덱스의 범위를 말해준다 , 0부터 시작해서 51490-1까지 존재하고 1씩 증가한다.
df.tail(3)
:마지막 3개의 행을 출력
#df.tail()은 마지막 5개 행을 출력
df.select_dtypes(exclude=object).columns
: 수치형 변수를 가진 컬럼을 출력
#.select_dtypes는 데이터 타입을 선택하는 명령어고 , exclude=object에서 object는 문자열 타입을 말한다
df.select_dtypes(include=object).columns
:범주형 변수를 가진 컬럼을 출력
df.isnull().sum()
: 각 컬럼의 결측치(NULL) 숫자를 파악하라
#.isnull()은 null값이 있는지 확인하는 명령어 , .sum은 합계를 표시하는 명령어
df.info()
:각 컬럼의 데이터수 , 데이터타입을 한번에 확인
df.describe()
:각 수치형 변수의 분포(사분위 평균 , 표준편차,최대,최소)를 확인
df['거주인구']
: 거주 인구 컬럼의 컬럼 값들을 출력
df['평균 속도'].quantile(0.75) - df['평균 속도'].quantile(0.25)
:평균 속도 칼럼의 4분위범위(IQR)값을 구하기
#4분위범위는 75%데이터 위치에서 25%데이터 위치를 빼는것이다.
#.qunatile(0.75)는 데이터의 75퍼센트 위치에서 뺄 수 있게 해주는 명령어이다.
df['읍면동명'].nunique()
:읍면동명 컬럼의 유일값 갯수를 출력
df['읍면동명'].unique()
:읍면동명 컬럼의 유일값을 모두 출력
-filtering , sorting (필터링 , 분류)
df [ df [ 'quantity' ] ==3 ].head()
: quantity 칼럼값이 3인 데이터를 추출하여 상위 5개 값을 출력해라
df.loc[ df ['quantity'] ==3 ].head().reset_index(drop=True)
:quantity 컬럼 값이 3인 데이터를 추출하여 index를 0부터 정렬해서 첫5행을 출력해라
#reset_index(drop=true)를 하면 원래 index값이 사라지고 0부터 다시 정렬된다.
#reset_index()를 하게되면 원래 index값으로 들어간다.
df2 = df[['quantity','item_price']]
: quantity , item_price 두개의 컬럼으로 구성된 새로운 데이터 프레임을 정의
#이때 2개 이상의 컬럼을 불러올때는 [ ] 처럼 괄호를 또 사용해야됨
df['new_price'] = df['item_price'].str[1:].astype('float')
Ans = df['new_price'].head()
Ans
:item_price 칼럼의 달러표시 문자를 제거하고 float타입으로 저장하여 new_price 칼럼에 저장하기
#.str[1:]은 문자열의 1첫번째부터 불러온다. 달러표시가 제일 앞에 있기 떄문에 달러 표시는 0번째라서 1번째부터 출력
#astype( ' ' ) : 따옴표 안에 데이터 형태로 바꿔주는 명령어
len(df[df['new_price'] <=5])
:new_price 컬럼이 5이하의 값을 가지는 데이터프레임을 추출하고, 전체 갯수를 구하여라
#len은 길이를 나타내는 명렁어이다.
df.loc[df.item_name =='Chicken Salad Bowl'].reset_index(drop=True)
:item_name명이 chicken salad bowl인 데이터 프레임을 추출하고 index값을 초기화하기
#df.loc[df.item_name] == df.loc[df [ itme_name] ]
Ans = df.loc[(df.item_name =='Chicken Salad Bowl') & (df.new_price <= 9)]
:new_price값이 9 이하이고 item_name 값이 Chicken Salad Bowl 인 데이터 프레임을 추출하라
Ans = df.sort_values('new_price').reset_index(drop=True)
:df의 new_price 컬럼 값에 따라 오름차순으로 정리하고 index를 초기화 하여라
#정렬을 할때 sort_values 명령어를 사용 , default는 오름차순
Ans = df.loc[df.item_name.str.contains('Chips')]
:df의 item_name 컬럼 값중 Chips 포함하는 경우의 데이터를 출력하라
#문자열에서 Chips가 포함되어야 하기 때문에 .str하고 .contains()를 사용한다.
Ans = df.iloc[:,::2]
df의 짝수번째 컬럼만을 포함하는 데이터프레임을 출력하라
#[ , ] 에서 :을 쓰면 모든것을 의미하고 ::2는 짝수번째를 말한다.
Ans = df.sort_values('new_price',ascending=False).reset_index(drop=True)
:new_price 칼럼값에 따라서 내림차순으로 정리하고 index를 초기화하기
#sort_values에서 ascending =False를 적으면 내림차순으로 정렬
Ans = df.loc[(df.item_name =='Steak Salad') | (df.item_name == 'Bowl')]
:item_name칼럼이 Steak Salad또는 item_name이 Bowl인 데이터를 인덱싱하기 ( 인덱스 초기화X)
Ans = df.loc[(df.item_name =='Steak Salad') | (df.item_name =='Bowl')]
Ans = Ans.drop_duplicates('item_name')
:df의 item_name 컬럼 값이 Steak Salad 또는 Bowl 인 데이터를 데이터 프레임화 한 후,
item_name를 기준으로 중복행이 있으면 제거하되 첫번째 케이스만 남겨라
#중복데이터를 제거하는 명령어 : drop_duplicates
#첫번쨰 케이스만 남기는건 defalut이고 마지막 케이스를 남길꺼면 drop_duplicates('~',keep='last')
Ans = df.loc[df.new_price >= df.new_price.mean()]
:new_price값이 new_price값의 평균값 이상을 가지는 데이터들을 인덱싱하라
#mean()은 평균값을 의미함
df.loc[df.item_name =='Izze','item_name'] = 'Fizzy Lizzy'
:df의 데이터 중 item_name의 값이 Izze 데이터를 Fizzy Lizzy로 수정하라
#item_name이 'lzze'일때 item_name에 'Fizzy Lizzy'를 넣어라
#loc는 df.ioc[ , ] 일때 [ 행 (조건) ,열 ] , 단일조건일때는 loc를 안써도 되지만 이럴떄는 써야함
Ans = df.choice_description.isnull().sum()
:choice_description 값이 Null 인 데이터의 갯수를 구하여라
df.loc[df.choice_description.isnull(),'choice_description'] ='NoData'
:choice_description 값이 Null 인 데이터를 NoData 값으로 대체하라(loc 이용)
Ans = df[df.choice_description.str.contains('Black')]
:choice_description 값에 Black이 들어가는 경우를 인덱싱하라
Ans = len(df.loc[~df.choice_description.str.contains('Vegetables')])
:choice_description 값에 Vegetables 들어가지 않는 경우의 갯수를 출력하라
#들어가지 '않는' 경우이기 때문에 ~를 붙여준다.
Ans = df[df.item_name.str.startswith('N')]
: item_name 값이 N으로 시작하는 데이터를 모두 추출하라
#~로 시작하는 데이터 검색을 할때는 startswith()를 사용한다.
Ans = df[df.item_name.str.len() >=15]
: item_name 값의 단어갯수가 15개 이상인 데이터를 인덱싱하라
#단어 갯수가 15개 이상이니까 str.len()>=15를 사용해준다. str(문자열)의 len(길이)을 볼때는 공백도 포함된다.
lst =[1.69, 2.39, 3.39, 4.45, 9.25, 10.98, 11.75, 16.98]
Ans = df.loc[df.new_price.isin(lst)]
print(len(Ans))
: new_price값이 lst에 해당하는 경우의 데이터 프레임을 구하고 그 갯수를 출력하라
lst =[1.69, 2.39, 3.39, 4.45, 9.25, 10.98, 11.75, 16.98]
#어떤값이 안에 있는지 확인할때는 isin(lst)을 사용한다.
-Grouping
Ans = df.host_name.value_counts().sort_index() 또는
Ans = df.groupby('host_name').size().sort_index()
:데이터의 각 host_name의 빈도수를 구하고 host_name으로 정렬하여 상위 5개 출력
#host_name의 빈도수를 구한다는 것은 host_name을 기준으로 그룹핑을 하는것이다.
#위에 counts와 size의 차이는 size는 null값이 있어도 수를 세지만 counts는 null값을 세지 않는다
#counts에서 null값을 읽을라고 하면 counts(dropna=false)
df.host_name.value_counts().to_frame().head() 또는
Ans = df.groupby('host_name').size().\
to_frame().rename(columns={0:'counts'}).\
sort_values('counts',ascending=False)
:데이터의 각 host_name의 빈도수를 구하고 빈도수로 정렬하여 상위 5개를 출력하라
#\표시는 엔터를 말한다. size().\to_frame() = size().to_frame
#to_frame()은 데이터 프레임화 한다는 뜻
Ans = df.groupby(['neighbourhood_group','neighbourhood'], as_index=False).size()
:neighbourhood_group의 값에 따른 neighbourhood컬럼 값의 갯수를 구하여라
#groupby를 할때도 [ , ]을 사용해서 2개를 그룹핑 할 수 있다.
#groupby는 열과 열을 불러오는 것이라서 dataframe타입이 아니라 series타입이다.
#as_index=False는 인덱스로 인식하지 않는다는 뜻이다. 이건 하나의 칼럼으로 지정된다.
Ans= df.groupby(['neighbourhood_group','neighbourhood'], as_index=False).size()\
.groupby(['neighbourhood_group'], as_index=False).max()
:neighbourhood_group의 값에 따른 neighbourhood컬럼 값 중 neighbourhood_group그룹의 최댓값들을 출력하라
Ans = df.groupby('neighbourhood_group')['price'].agg(['mean','var','max','min'])
:neighbourhood_group 값에 따른 price값의 평균, 분산, 최대, 최소 값을 구하여라
#agg는 사칙연산을 뭐할건지를 선언해주는 것
#사칙연산을 여러가지 하기 떄문에 [ ] 로 묶어준다.
Ans = df.groupby('neighbourhood_group')['reviews_per_month'].agg(['mean','var','max','min'])
:neighbourhood_group 값에 따른 reviews_per_month 평균, 분산, 최대, 최소 값을 구하여라
#위에랑 비슷함
Ans = df.groupby(['neighbourhood','neighbourhood_group']).price.mean()
:neighbourhood 값과 neighbourhood_group 값에 따른 price 의 평균을 구하라
#위에랑 비슷한데 groupby을 2개하는 것이다.
#여기서 as_index=False를 쓰면 좀 더 이쁘게 나온다.
Ans = df.groupby(['neighbourhood_group', 'neighbourhood']).price.mean().unstack()
:neighbourhood 값과 neighbourhood_group 값에 따른 price 의 평균을 계층적 indexing 없이 구하라
#계층적 index를 구하는 것은 unstack()을 사용하면 구할수있다.
Ans = df.groupby(['neighbourhood','neighbourhood_group']).price.mean().unstack().fillna(-999)
: neighbourhood 값과 neighbourhood_group 값에 따른 price 의 평균을 계층적 indexing 없이 구하고 nan 값은 -999값으로 채워라
#fillna(숫자) 는 채울것이다(fill) na(Null)값을 숫자값으로
Ans=df[df.neighbourhood_group=='Queens'].groupby(['neighbourhood']).price.agg(['mean','var','max','min'])
:데이터중 neighbourhood_group 값이 Queens값을 가지는 데이터들 중 neighbourhood 그룹별로 price값의 평균, 분산, 최대, 최소값을 구하라
#neighbourhood_group 값이 Queens값을 가지는 데이터들 중 //
#neighbourhood 그룹별로//
#price값의 평균, 분산, 최대, 최소값을 구하라 -> 3번 잘라서 생각하면 편함
Ans = df[['neighbourhood_group','room_type']].groupby(['neighbourhood_group','room_type'])
.size().unstack()
Ans.loc[:,:] = (Ans.values /Ans.sum(axis=1).values.reshape(-1,1))
:데이터중 neighbourhood_group 값에 따른 room_type 컬럼의 숫자를 구하고 neighbourhood_group 값을 기준으로 각 값의 비율을 구하여라
#neighbourhood_group 값에 따른 room_type 컬럼의 숫자를 구하고//
#neighbourhood_group 값을 기준으로//
#각 값의 비율을 구하여라
#loc[:,:] = 모든 열과 모든 행을 가져온다는 의미
#Ans.sum(axis=1)은 행(row)을 기준으로 합을 한다는 의미이다 , 가로로 다 더한다는 의미
#Ans.values는 각 값에 대한 array(배열)을 뽑아준다. , values는 값만 빼온다
#reshape(-1,1)은 1차원 배열로 만들어준다는 것이다.
#배열끼리의 사칙연산을 할때는 같은 차원이여야 계산이 되기 때문에 같은 차원으로 만들어준다.
-Apply , Map
Income_Category의 카테고리를 map 함수를 이용하여 다음과 같이 변경하여 newIncome 컬럼에 매핑하라
Unknown : N
Less than $40K : a
$40K - $60K : b
$60K - $80K : c
$80K - $120K : d
$120K +’ : e 으로 바꿀것이다.
dic = {
'Unknown' : 'N',
'Less than $40K' : 'a',
'$40K - $60K' : 'b',
'$60K - $80K' : 'c',
'$80K - $120K' : 'd',
'$120K +' : 'e'
}
df['newIncome'] = df.Income_Category.map(lambda x: dic[x])
Ans = df[['newIncome', 'Income_Category']]
#map(lamda x : dic[x]) 일때 lamda x는 앞에있는 변수를 x로 본다 즉, Income_Category를 x로 보겠다 라는 뜻
#dic[x]는 dic에 Income_Category를 넣어주겟다 라는 뜻 -> Income_Category가 맵핑이 되면서 어떻게 변화하는지 본다.
Income_Category의 카테고리를 apply 함수를 이용하여 다음과 같이 변경하여 newIncome 컬럼에 매핑하라
def changeCategory(x):
if x =='Unknown':
return 'N'
elif x =='Less than $40K':
return 'a'
elif x =='$40K - $60K':
return 'b'
elif x =='$60K - $80K':
return 'c'
elif x =='$80K - $120K':
return 'd'
elif x =='$120K +' :
return 'e'
df['newIncome'] =df.Income_Category.apply(changeCategory)
#apply는 함수를 넣는다는 느낌이고 map은 문자열을 넣는 느낌
:Customer_Age의 값을 이용하여 나이 구간을 AgeState 컬럼으로 정의하라. (0-9: 0 , 10-19: 10 , 20-29: 20) …
각 구간의 빈도수를 출력하라
df['AgeState'] = df.Customer_Age.map(lambda x: x//10 10)
Ans = df['AgeState'].value_counts().sort_index()
#32//10 = 3 -> //는 몫을 나타낸다 , 나이별로 나타내야 하기 때문에 19살이면 10~19//10 10 = 10이라서 사용한다.
#map대신 apply를 사용해도 된다. 하지만 보통 함수를 적용할떄는 apply를 사용하고 , dictionary를 적용할때는 map을 사용한다
:Education_Level의 값중 Graduate단어가 포함되는 값은 1 그렇지 않은 경우에는 0으로 변경하여
newEduLevel 컬럼을 정의하고 빈도수를 출력하라
df['newEduLevel'] = df.Education_Level.map(lambda x : 1 if 'Graduate' in x else 0)
Ans = df['newEduLevel'].value_counts()
#if~elseif를 한줄로 대신 lamda x :1 if '변수' in x else 0 은 만약 x에 변수가 있다면 1을 출력하고 아니면 0을 출력한다는 뜻
#같은 결과지만 다른 코드
#import numpy as np
#df['newEduLevel'] = np.where( df.Education_Level.str.contains('Graduate'), 1, 0)
#Ans = df['newEduLevel'].value_counts()
#np.where은(조건,1,0)이면 조건을 만족하면 1이고 아니면 0을 적용해라 라는 뜻
Credit_Limit 컬럼값이 4500 이상인 경우 1 그외의 경우에는 모두 0으로 하는 newLimit 정의하라.
newLimit 각 값들의 빈도수를 출력하라
df['newLimit'] = df.Credit_Limit.map(lambda x : 1 if x>=4500 else 0)
Ans = df['newLimit'].value_counts()
#만약 x가 4500이상이면 1 , 아니면 0을 넣으라는 뜻
#빈도수를 출력하기 때문에 value_counts를 사용
Marital_Status 컬럼값이 Married 이고 Card_Category 컬럼의 값이 Platinum인 경우 1 그외의 경우에는 모두 0으로 하는 newState컬럼을 정의하라.
newState의 각 값들의 빈도수를 출력하
def check(x):
if x.Marital_Status =='Married' and x.Card_Category =='Platinum':
return 1
else:
return 0
df['newState'] = df.apply(check,axis=1)
Ans = df['newState'].value_counts()
#apply를 하기 위해서 check(x)함수를 정의해준다. , apply를 열기준으로 적용할것이기 때문에 axis=1을 써준다.
#위에는 df.칼럼.apply를 했는데 여기는 df.apply이다.
#그 이유는 우리가 지금 조건을 건 데이터는 M , P 2개이기 때문에 하나의 칼럼을 x로 선언해서 이 데이터에 대한 체크를 할 수 없다.
#즉 하나하나 대입이 안되기 때문에 열을 기준으로 비교한다.
Gender 컬럼값 M인 경우 male F인 경우 female로 값을 변경하여 Gender 컬럼에 새롭게 정의하라.
각 value의 빈도를 출력하라.
def changeGender(x):
if x =='M':
return 'male'
else:
return 'female'
df['Gender'] = df.Gender.apply(changeGender)
Ans = df['Gender'].value_counts()
-Time_series
Yr_Mo_Dy을 판다스에서 인식할 수 있는 datetime64타입으로 변경하라
:df.Yr_Mo_Dy = pd.to_datetime(df.Yr_Mo_Dy)
Yr_Mo_Dy에 존재하는 년도의 유일값을 모두 출력
:Ans = df.Yr_Mo_Dy.dt.year.unique()
#dt.year는 '년'만 추출 , dt.month 는 월만 추출 , dt.day는 일만 추출
Yr_Mo_Dy에 년도가 2061년 이상의 경우에는 모두 잘못된 데이터이다.
해당경우의 값은 100을 빼서 새롭게 날짜를 Yr_Mo_Dy 컬럼에 정의하라
:def fix_century(x):
import datetime
year = x.year - 100 if x.year >= 2061 else x.year
return pd.to_datetime(datetime.date(year, x.month, x.day))
df['Yr_Mo_Dy'] = df['Yr_Mo_Dy'].apply(fix_century)
#fix_century에서 year는 datetime 변수가 아니라 정수형 변수가 되기 때문에 pd.to_datetime으로 datetime형태로 변환
년도별 각컬럼의 평균값을 구하여라
:Ans = df.groupby(df.Yr_Mo_Dy.dt.year).mean(numberic_only=True)
#numberic_only=True 문자열같은 것 말고 오직 숫자만 계산하겠다.
weekday컬럼을 만들고 요일별로 매핑하라 ( 월요일: 0 ~ 일요일 :6)
:df['weekday'] = df.Yr.Mo.Dt.dt.weekday
#weekday는 요일을 추출한다 , 월요일은 0 으로 시작해서 일요일 6으로 끝난다
weekday컬럼을 기준으로 주말이면 1 평일이면 0의 값을 가지는 WeekCheck 컬럼을 만들어라
:df['WeekCheck'] = df['weekday'].map(lambda x : 1 if x in [5,6] else 0)
년도, 일자 상관없이 모든 컬럼의 각 달의 평균을 구하여라
:Ans=df.groupby(df.Yr_Mo_Dy.dt.month).mean(numberic=True)
모든 결측치는 컬럼기준 직전의 값으로 대체하고 첫번째 행에 결측치가 있을경우 뒤에있는 값으로 대체하라
:df = df.fillna(method='ffill').fillna(method='bfill')
df.insull().sum() <---------null값이 있는 확인하기
#method = 'ffill' = first fill = 앞에있는거를 채워주겠다.
#method = 'bfill' = back fill = 뒤에 있는거를 채워준다. -----> 결국 그러면 앞에가 null이면 뒤에값으로 채우고해서 null을 제거
년도 - 월을 기준으로 모든 컬럼의 평균값을 구하여라
:Ans = df.groupy(df.Yr_Mo_Dy.dt.to_period('M')).mean(numberic=True)
#to_period('M') : Y-M으로 보여줌 ( 1961-01 )
년도 - 월을 기준으로 모든 컬럼의 최대값을 구하여라
:Ans = df.groupby(df.Yr_Mo_Dy.dt.to_period('M')).max(numeric_only=True)
RPT와 VAL의 컬럼을 일주일 간격으로 각각 이동평균한값을 구하여라
:Ans = df[ [ 'RPT','VAL'] ].rolling(7).mean()
#일주일 간격으로 이동평균이란? 0~5까지는 아직 7개가 되지 않기때문에 Null이지만 6번이 되면 7개가 되기때문에 그때부터
평균값이 만들어지고 , 6번에서는 0~6까지의 평균, 7번에서는 1~7까지의 평균을 구하는 것이 일주일 간격 이동평균이다.
#이동평균을 구할때 rolling을 사용
년-월-일:시 컬럼을 pandas에서 인식할 수 있는 datetime 형태로 변경하라. 서울시의 제공데이터의 경우 0시가 24시로 표현된다
:def change_date(x):
import datetime
hour = x.split(':')[1]
date = x.split(":")[0]
if hour =='24':
hour ='00:00:00'
FinalDate = pd.to_datetime(date +" "+hour) + datetime.timedelta(days=1)
else:
hour = hour +':00:00'
FinalDate = pd.to_datetime(date +" "+hour)
return FinalDate
df['(년-월-일:시)'] = df['(년-월-일:시)'].apply(change_date)
#split(' : ') = :을기준으로 데이터를 나누겠다 , df['(년-월-일:시)'][0].split(':')의 의미는 년-월-일:시로 되어있는 데이터에서
:을 기준으로 나눴을때 0번째의 값을 가져온다는 의미이다. 만약 2022-05-15:15이면 :을 기준으로 나누면
2022-05-15 와 15가 있는데 그중에 0번째 값이라는 것은 2022-05-15이고 1번째값은 15인 것이다. 2개로 나누어진 것이다.
#2022-05-15:24 이면 2022-05-16:00과 같은 의미라서 if hour==24이면 시간을 00으로 지정하고 날짜는 하루를 추가하기 위해서 원래 날짜에 + datetime.timedelta(days=1)을 사용해서 1일을 추가한다.
#timedelta(days=1)은 하루가 넘어간다는 소리이다.
일자별 영어요일 이름을 dayName 컬럼에 저장하라
:df['dayName'] = df['('년-월-일:시)'].dt.day_name()
#day_name()은 요일이름을 알려주는 명령어이다.
요일별 각 PM10등급의 빈도수를 파악하라
:Ans1 = df.groupby(['dayName','PM10등급'],as_index=False).size()
Ans2 = Ans1.pivot(index='dayName',columns='PM10등급',values='size').fillna(0)
#pivot(피벗) : 데이터를 다시 행과 열과 값으로 변환하는 것
#pivot(index , column , value) 형식으로 구성되고 index는 왼쪽 행에 존재 , column은 열에다가 등급을 넣어주고
value에는 size를 넣는다. 만약 null값이 있으면 fillna(0)으로 null대신 0을 넣는다.
시간이 연속적으로 존재하며 결측치가 없는지 확인하라
:check = len(df['(년-월-일:시)'].diff().unique())
if check ==2:
Ans =True
else:
Ans = False
#.diff()라는 것은 바로 앞에 있는 것들을 다 뺀다는 뜻
#이때 첫번째 값은 Null이 되고 2번째 값은 그 뒤에 있는 값들을 전부다 뺀다는 것이라 하루차이가 나는 데이터 ,
#즉 , [Null,하루차이나는데이터] 이렇게 2개의 데이터만 있어야 하는게 정상이라서 2개의 데이터가 있으면
#시간이 연속적이라고 생각하는 것이고 그 외면 연속적이지 않다라고 판단한다.
오전 10시와 오후 10시(22시)의 PM10의 평균값을 각각 구하여라
:Ans = df.groupby(df['(년-월-일:시)'].dt.hour).mean(numeric_only=True).iloc[[10,22],[0]]
#뒤에 iloc[[10,22],[0]]이라는 뜻은 , 10~22시 까지에서 PM10의 평균이니까 PM10은 0번쨰 칼럼이기 때문에 [0]인것이다.
날짜 컬럼을 index로 만들어라
:df.set_index('(년-월-일:시)',inplace=True)
#set_index는 index를 어떤 column으로 지정할지 하는 명령어 , inplace = True는 반영된 값을 바로 원본 데이터에 적용한다.