01 Getting & Knowing Data
#11. 수치형 변수를 가진 컬럼을 출력하라
df.select_dtypes(exclude='O').columns
################select_dtypes에는 꼭 s를 붙여라 제발
################컬럼 출력하라는데 .columns를 붙여야하지 않겠니?!?!??!?
- select_dtypes에는 꼭 s를 붙여라 제발
02 Filtering & Sorting
#22. quantity컬럼 값이 3인 데이터를 추출하여 index를 0부터 정렬하고 첫 5행을 출력하라
df[df['quantity']==3].reset_index(drop=True).head()
#############drop=True를 써야해!!!!!!!!
#23. quantity , item_price 두개의 컬럼으로 구성된 새로운 데이터 프레임을 정의하라
df[['quantity','item_price']] ###########안에 대괄호로 한 번 더 묶는 거 깜빡함 정신체리자
- 대괄호로 한 번 더 묶는 거 깜빡함 정신체리자
#24. item_price 컬럼의 달러표시 문자를 제거하고 float 타입으로 저장하여 new_price 컬럼에 저장하라
df['new_price']=df['item_price'].str[1:].astype('float')
df['new_price']
########어떻게 했던 것 같은데 기억이 안 나욤
#####df['item_price'].str[1:] ************ str을 잊지 말자!!!!!!
#####astype -> 데이터타입 변경하는 메서드
- 문자열에서는 str을 잊지 말자!!!!!!
- astype('데이터타입') -> 데이터타입 변경하는 메서드
#27. new_price값이 9 이하이고 item_name 값이 Chicken Salad Bowl 인 데이터 프레임을 추출하라
cond1 = df['new_price'] <= 9
cond2 = df['item_name'] == 'Chicken Salad Bowl'
df[cond1 & cond2]
##df[(df['new_price'] <= 9) & (df['item_name'] == 'Chicken Salad Bowl')]
##조건을 괄호로 명확히 묶지 않으면 연산자 우선순위로 인해 오류남
################
- 조건을 괄호로 명확히 묶지 않으면 연산자 우선순위로 인해 오류남
#29. df의 item_name 컬럼 값중 Chips 포함하는 경우의 데이터를 출력하라
cond = df['item_name'].str.contains('Chips')
df[cond]
##########contains를 까먹으면 어카니 증말!!!!!!!!!!
- menu.isin(['맛난버거 세트', '더블 치즈버거']) ## isin은 정확일치, 여러개 가능
- menu.str.contains('세트') ## contains는 일부일치, 한개만
#30. df의 짝수번째 컬럼만을 포함하는 데이터프레임을 출력하라
df.iloc[:,::2]
#################[:,:,2]이게 아니라 [:,::2] 이거다 정신차려랏
#33. df의 item_name 컬럼 값이 Steak Salad 또는 Bowl 인 데이터를 데이터 프레임화 한 후,
#item_name를 기준으로 중복행이 있으면 제거하되 첫번째 케이스만 남겨라
cond = (df['item_name']=='Steak Salad') | (df['item_name']=='Bowl')
df = df[cond]
df.drop_duplicates('item_name') ###############
#############drop_duplicates 이걸 몰랐네 내가..
#34. df의 item_name 컬럼 값이 Steak Salad 또는 Bowl 인 데이터를 데이터 프레임화 한 후,
#item_name를 기준으로 중복행이 있으면 제거하되 마지막 케이스만 남겨라
cond = (df['item_name']=='Steak Salad') | (df['item_name']=='Bowl')
a = df[cond]
a.drop_duplicates('item_name', keep='last')###########
#############keep='last' 몰랐으니까 외워 그냥
- drop_duplicates('컬럼명')
- 중복행 있으면 제거
- 기본적으로 첫번째 케이스 남기고 중복 제거
- 중복 제거 시 마지막 케이스 남기려면 drop_duplicates('컬럼명', keep = 'last')
#38. df의 데이터 중 choice_description 값이 NaN 인 데이터를 NoData 값으로 대체하라(loc 이용)
cond = df['choice_description'].isnull()
df.loc[cond,'choice_description'] = 'NoData' ##데이터프레임에 바로 반영되니까 대입할 필요가 없구나...
df
############### loc 사용해서 데이터 대체하는 거 좀 헷갈림
#41 df의 데이터 중 item_name 값이 N으로 시작하는 데이터를 모두 추출하라
df[df['item_name'].str[:1] == 'N']
##df[df.item_name.str.startswith('N')]
##startswith로 찾을 수도 있음
- startwith() : ~로 시작하는 데이터 찾기
#43. df의 데이터 중 new_price값이 lst에 해당하는 경우의 데이터 프레임을 구하고
#그 갯수를 출력하라
lst =[1.69, 2.39, 3.39, 4.45, 9.25, 10.98, 11.75, 16.98]
df[df['new_price'].isin(lst)]
#############isin()을 완전히 까먹고 있었어,...
03_Grouping
#45. 데이터의 각 host_name의 빈도수를 구하고 host_name으로 정렬하여 상위 5개를 출력하라
df.groupby('host_name').size().sort_index()
##########sort_index() 사용해야함
### 인덱스 기준 정렬 (기본값 ascending=True)
- 여기서는 'host_name' 으로 그룹화해서 'host_name'이 인덱스가 됨
- sort_index()
#46. 데이터의 각 host_name의 빈도수를 구하고
#빈도수 기준 내림차순 정렬한 데이터 프레임을 만들어라. 빈도수 컬럼은 counts로 명명하라
###########틀린 코드
df['counts'] = df['host_name'].value_counts().sort_values(ascending=False)
df['counts']
## 다 널값으로 채워짐
## 왜??
###->df['host_name'].value_counts()는 각 호스트 이름별로 등장 횟수(빈도수)를 세어서 Series로 반환 (이 Series의 인덱스는 host_name의 고유값(예: 'Alice', 'Bob' 등))
###->반면, df['counts'] = ...로 할당할 때는 **DataFrame의 행 인덱스(0, 1, 2, ...)**와 **Series의 인덱스(호스트 이름)**가 일치하지 않으므로, 자동 정렬/매칭이 되지 않습니다.
###df['counts'] = df['host_name'].map(df['host_name'].value_counts())
###map()은 host_name의 각 값에 대해 value_counts의 결과를 매칭
#46. 데이터의 각 host_name의 빈도수를 구하고
#빈도수 기준 내림차순 정렬한 데이터 프레임을 만들어라. 빈도수 컬럼은 counts로 명명하라
Ans = df.groupby('host_name').size().\
to_frame().rename(columns={0:'counts'}).\
sort_values('counts',ascending=False)
Ans
###########이건 그냥 외우는 것이... 외울게 너무 많은데 그러면....
##groupby('something').size - > 그룹바이로 묶인 데이터의 개수를 센다
##to_frame().rename(columns={0:'counts'}) 데이터프레임으로 만들고, 이름 다시 명명
#48-1. neighbourhood_group의 값에 따른 neighbourhood컬럼 값 중
# neighbourhood_group그룹의 최댓값들을 출력하라
a = df.groupby(['neighbourhood_group','neighbourhood']).size().reset_index()
a.groupby(['neighbourhood_group']).max()\
##df.groupby(['neighbourhood_group','neighbourhood']).size()
##-> 이렇게 하면 'neighbourhood_group','neighbourhood'가 인덱스인 데이터프레임이 만들어짐
##reset_index()에 drop=True 넣으면 인덱스 다 사라져서 다음에 'neighbourhood_group' 으로 묶을 수 없어서 넣으면 안됨
#48-2. neighbourhood_group의 값에 따른 neighbourhood컬럼 값 중
# neighbourhood_group그룹의 최댓값들을 출력하라
# a = df.groupby(['neighbourhood_group','neighbourhood']).size().reset_index()
# a.groupby('neighbourhood_group').max()\
Ans= df.groupby(['neighbourhood_group','neighbourhood'], as_index=False).size()\
.groupby(['neighbourhood_group'], as_index=False).max()
Ans
##as_index=False를 쓰면 reset_index()를 쓰지 않아도 같은 효과~
- as_index=False를 쓰면 reset_index()를 쓰지 않아도 같은 효과
#49-1. neighbourhood_group 값에 따른 price값의 평균, 분산, 최대, 최소 값을 구하여라
df.groupby('neighbourhood_group')['price'].agg(['mean','var','max','min'])
########### 수치 여러개 쓰려면 agg 쓸 것
#52. neighbourhood 값과 neighbourhood_group 값에 따른 price 의 평균을 계층적 indexing 없이 구하라
##인덱싱 없이구하라는게 먼 말임?
df.groupby(['neighbourhood','neighbourhood_group'])['price'].mean().unstack()
########계층적 인덱싱 없이 구하라는게 먼 말인지는 모르겠고
## unstack()은 가장 마지막의 인덱스를 컬럼으로 변경 가능한 것을 말함
- unstack() : 가장 마지막의 인덱스를 컬럼으로 변경 가능한 것
#54. 데이터중 neighbourhood_group 값이 Queens값을 가지는 데이터들 중
#neighbourhood 그룹별로 price값의 평균, 분산, 최대, 최소값을 구하라
cond = df['neighbourhood_group']=='Queens'
df[cond].groupby('neighbourhood')['price'].agg(['mean','var','max','min'])
######### agg(['mean','var','max','min']) 여기에서 집계함수들 []로 묶어줘야하는데 그걸 안 했어!!
- 집계함수들 여러개 넣을 때 agg안에서 [ ]로
- ex) agg(['mean','var','max','min'])
#55. 데이터중 neighbourhood_group 값에 따른 room_type 컬럼의 숫자를 구하고
#neighbourhood_group 값을 기준으로 각 값의 비율을 구하여라
a = df.groupby('neighbourhood_group')['room_type'].size()
a_sum = a.sum()
a
b = df[['neighbourhood_group','room_type']].groupby(['neighbourhood_group','room_type']).size().unstack()
b['sum'] = a
# 각 room_type별 비율 컬럼으로 변환
b[['Entire home/apt', 'Private room', 'Shared room']] = (
b[['Entire home/apt', 'Private room', 'Shared room']].div(b['sum'], axis=0)
)
b
######각 행의 다른 컬럼 값으로 나누고 싶으면 div 쓰셈...
# a = df[['neighbourhood_group','room_type']].groupby(['neighbourhood_group','room_type']).size().unstack()
# a.loc[:,:]=(a.values/a.sum(axis = 1).values.reshape(-1,1))
# a
- div( ) : 행의 들을 같은 행 다른 컬럼 값으로 나누고 싶을 때 사용 가능
#62. Marital_Status 컬럼값이 Married 이고 Card_Category 컬럼의 값이 Platinum인 경우 1 그외의 경우에는 모두 0으로 하는 newState컬럼을 정의하라.
# newState의 각 값들의 빈도수를 출력하라
#############################그냥 개어렵잖아
def a(x):
if x['Marital_Status'] == 'Married' and x['Card_Category'] == 'Platinum':
return 1
else:
return 0
df['newState'] = df.apply(a,axis = 1) ###a 함수는 기본적으로 열 단위로 가져오고 있어서 axis = 1을 해줘야 행 단위로 input값이 들어감
df['newState'].value_counts()
- a 함수는 기본적으로 열 단위로 가져오고 있어서 axis = 1을 해줘야 행 단위로 input값이 들어감
05_Time_Series
#65. Yr_Mo_Dy을 판다스에서 인식할 수 있는 datetime64타입으로 변경하라
df['Yr_Mo_Dy'] = pd.to_datetime(df['Yr_Mo_Dy'])
df['Yr_Mo_Dy']
#############df.to_datetime()이 아니고 pd.to_datetime(df)이다!!!!!!!!!!!!!!!
################티스토리 판다스 시계열에 적어둔 거랑 같은 실수 또함 정신차리자
- df.to_datetime()이 아니고 pd.to_datetime(df)
#72. 모든 결측치는 컬럼기준 직전의 값으로 대체하고 첫번째 행에 결측치가 있을경우 뒤에있는 값으로 대채하라
# df.isnull().sum()
df.fillna(method = 'ffill').fillna(method = 'bfill')
######## method = 'bfill', method를 까먹었네 , 그리고 bfill에 따옴표 까먹지마
- 직전 값으로 대체 method = 'ffill' / 뒤에 있는 값으로 대체 method = 'bfill'
- method = 'bfill', method를 까먹었네 , 그리고 bfill에 따옴표 까먹지마
#74. RPT 컬럼의 값을 일자별 기준으로 1차차분하라
df['RPT'].diff()
##################### 1차차분은 diff()래
#75. RPT와 VAL의 컬럼을 일주일 간격으로 각각 이동평균한값을 구하여라
df[['RPT','VAL']].rolling(7).mean()
################이동평균은 rolling(간격).mean()
#76. 년-월-일:시 컬럼을 pandas에서 인식할 수 있는 datetime 형태로 변경하라.
# 서울시의 제공데이터의 경우 0시가 24시로 표현된다
# df.info()
# df['(년-월-일:시)'] #2021-05-15:15
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)
Ans = df
Ans
####################이렇게까지 나온다고 진짜...
##########걍 쳐다보기만함
#77. 일자별 영어요일 이름을 dayName 컬럼에 저장하라
day_name={0:'Monday',1:'Tuesday',2:'Wednesday',3:'Thursday',4:'Friday',5:'Satueday',6:'Sunday'}
df['dayName'] = df['(년-월-일:시)'].dt.weekday.map(day_name)
df['dayName']
########## weekday에는 뒤에 ()안 붙는다
- weekday에는 뒤에 ()안 붙는다
- dt.year
dt.month
dt.day
dt.hour
dt.minute
dt.second
얘네 다 뒤에 () 안 붙는다
- dayofweek랑 weekday 똑같음
#78. 일자별 각 PM10등급의 빈도수를 파악하라
df[['(년-월-일:시)','PM10등급']].groupby([df['(년-월-일:시)'].dt.date,'PM10등급']).size().reset_index()
############################
- 약간 헷갈리면 필요한 컬럼만 빼서 일단 출력해봐
#79. 시간이 연속적으로 존재하며 결측치가 없는지 확인하라
df['(년-월-일:시)'].diff().unique()
#81. 날짜 컬럼을 index로 만들어라
df.set_index('(년-월-일:시)')
########### set_index()를 활용
- set_index('컬럼명') : 컬럼을 지정해서 인덱스로 만들 수 있음
#82. 데이터를 주단위로 뽑아서 최소,최대 평균, 표준표차를 구하여라
Ans = df.resample('W').agg(['min','max','mean','std'])
################ resample() 먼소리람
- df.resample('W') : 데이터를 주단위로 뽑음
#88. 한국 올림픽 메달리스트 데이터에서 년도에 따른 medal 갯수를 데이터프레임화 하라
df_kor.pivot_table(index='Year',columns='Medal',aggfunc='size')
###묶어서 개수 구할 때는 무조건 size야
07_Merge , Concat
#91. df1과 df2 데이터를 하나의 데이터 프레임으로 합쳐라
pd.concat([df1,df2])
############ df.concat 아니고 pd.concat !!!!!!!!!
############ [df1,df2] 데이터프레임은 꼭 대괄호로 묶어라 제발
- df.concat 아니고 pd.concat !!!!!!!!!
- [df1,df2] 데이터프레임은 꼭 대괄호로 묶어라 제발
#92. df3과 df4 데이터를 하나의 데이터 프레임으로 합쳐라. 둘다 포함하고 있는 년도에 대해서만 고려한다
pd.concat([df3,df4],join = 'inner')
####### 둘 다 포함하는 년도에 대해서만 합치면 -> join = 'inner' 쓰면 된다
- join = 'inner' 은 교집합
- join 안 쓰면 기본은 join = 'outer' 로 합집합이다.
#94. df5과 df6 데이터를 하나의 데이터 프레임으로 merge함수를 이용하여 합쳐라.
# Algeria컬럼을 key로 하고 두 데이터 모두 포함하는 데이터만 출력하라
pd.merge(df5,df6, on = 'Algeria', how = 'inner')
- 특정 컬럼을 기준으로 합칠 때는 merge
- 특정 컬럼 지정은 on = 'Algeria'으로 함
ex) pd.merge(df5,df6, on = 'Algeria', how = 'inner')
- merge는 기본이 inner로 설정, outer조인하려면 how = 'outer' 지정해줘야함