#pandas 패키지를 이용한 시각화.
'''
line: 선 그래프
bar: 막대 그래프
barh: 수평 막대 그래프
hist: 히스토그램
box: 박스 플롯
kde: 커널 밀도 그래프
area: 면적 그래프
pie: 파이 그래프
scatter: 산점도 그래프
hexbin: 고밀도 산점도 그래프
'''

import seaborn as sns
 
df = sns.load_dataset('diamonds')



#다이아몬드, 무게(carat)와 가격(price)의 관계

import pandas as pd
import matplotlib.pyplot as plt
plt.rc('font', family='Malgun Gothic')

df.plot.scatter(x='carat', y='price', figsize=(10, 6), title='캐럿과 가격 간의 관계')

plt.show()


#커팅의 가치(cut)별로 점 색을 다르게 표현하기(예쁨)

df.plot.scatter(x='carat', y='price', c='cut', cmap='Set2', figsize=(10, 6))
plt.show()






#다이아몬드 가격(price)을 히스토그램으로 표현하기
import seaborn as sns
df = sns.load_dataset('diamonds')

import pandas as pd
import matplotlib.pyplot as plt
plt.rc('font', family='Malgun Gothic')

df['price'].plot.hist(figsize=(10, 6), bins=20)  # price열만 표현하고 싶다고 선택.
plt.show()




# 다이아몬드 색(color) 별로 무게(carat)의 평균을 막대 그래프로 나타내기. (분석&시각화를 동시에 함)
import seaborn as sns
df = sns.load_dataset('diamonds')

import pandas as pd
import matplotlib.pyplot as plt
plt.rc('font', family='Malgun Gothic')

df.groupby('color')['carat'].mean().plot.bar(figsize=(10, 6))
#그룹바이 컬러, 그다음 carat의 평균을 구하고, 구해진 값에 바로 plot.bar() 메서드 적용해서 막대 그래프로 표현한다.
plt.show()


 

 

 

#seaborn 패키지는 matplotlib보다 좀 더 화려하고 복잡한 그래프

import seaborn as sns
import matplotlib.pyplot as plt

df = sns.load_dataset('titanic')


#나이와 운임의 관계, 산점도 그래프
sns.scatterplot(data=df, x='age', y='fare')
plt.show()

#각 그룹별로 점의 색, 모양을 다르게 표시하기
import seaborn as sns
import matplotlib.pyplot as plt

df = sns.load_dataset('titanic')

sns.scatterplot(data=df, x='age', y='fare', hue='class', style='class') #hue는 색이고 style은 점 모양인데 둘 다 클래스에 따라서 달라지도록 설정함.
plt.show() # 자동으로 다 설정해 줌.





# matplotlib나 pandas로 못하는 것. 히트맵? 과 같은 복잡한 그림? (완전 좋음.)

#1. 각 클래스와 성별에 따른 생존율을 계산해 보자.
import seaborn as sns
import matplotlib.pyplot as plt

df = sns.load_dataset('titanic')

df_pivot = df.pivot_table(index='class', #행인덱스(맨 왼쪽 세로 줄로 표시)
                          columns= 'sex', #열 인덱스(맨 위 가로 줄로 표시)
                          values='survived', #넣을 값.
                          aggfunc='mean') #aggfunc(==집계함수)는 평균을 사용.(survived열에서 1은 생존, 0은 사망을 의미하므로 평균==생존율이다.)

print(df_pivot)

#위 결과를 히트맵으로 나타내면?

sns.heatmap(df_pivot, annot=True, cmap='BrBG')  

#heatmap()함수 안에 df_pivot테이블 넣음.
#annot은 데이터 값을 표시할지 여부, cmap은 팔레트 종류로, coolwarm은 값이 높을수록 붉은색, 낮을수록 푸른 색이다.
plt.show()






#한 번에 여러 개의 그래프 나타내기

'''
1. figure-level: (뭔가 그래프를 그리는 캔버스 자체, 그림판 레벨이라는 뜻)
matplotlib와 별개로 seaborn의 figure를 만들어 그곳에 그래프를 나타낸다.
여러 개의 그래프를 나타낼 때, facetgrid(seaborn의 figure)를 통해 레이아웃을 변경해야 함.
함수 이름: replot, displot, catplot

2. axes-level: (그래프 레벨에서 조정한다는 뜻)
그냥 matplotlib의 axes에 그래프를 나타냄.

'''

#figure-level의 예제. class별 나이 분포
import seaborn as sns
import matplotlib.pyplot as plt

df = sns.load_dataset('titanic')

sns.displot(data=df, x='age', hue='class', kind='hist', alpha=0.3)
#kind(그래프 종류)=히스토그램, hue(색 구분)=class별로 구분하겠다. alpha(투명도 조절)=0.3)
plt.show()


#위의 그래프를 각각 개별 그래프로 표현해 보자. (histplot()은 axes-level이라서 여러 그래프 못 나타냄.)
sns.displot(data=df, x='age', col='class', kind='hist') #col인자에 특정 열을 입력하면 해당 열을 기준으로 그래프가 각각 분할됨.

plt.show() #클래스 1그래프, 클래스2 그래프, 클래스 3 그래프 이렇게 세 개가 가로로!(열 분할했으니까) 쭉 나온다.

sns.displot(data=df, x='age', col='class', row='sex', kind='hist')
#행으로는 sex, 열로는 class별로 구분되었다. 위에는 male- class 1, 2, 3 그래프가, 아래는 female- 1, 2, 3그래프가 나온다.
plt.show()




#axes-level의 예제. class별 나이 분포와 평균 나이
import seaborn as sns
import matplotlib.pyplot as plt

df = sns.load_dataset('titanic')

plt.rc('font', family='malgun Gothic')
g, axes = plt.subplots(2, 1, figsize=(8, 6))

sns.histplot(data=df, x='age', hue='class', ax=axes[0]) #히스토그램을 그린 다음에 ax=axes[0]을 쓰면 첫 번째 axes에 해당 그래프가 출력된다.
sns.barplot(data=df, x='class', y='age', ax=axes[1]) #두 번째 axes에 해당 그래프를 출력

axes[0].set_title('클래스별 나이 분포도') #제목 변경하는 법.
axes[1].set_title('클래스별 평균 나이')

g.tight_layout() #여백이 조정된다.
plt.show()
#1.matplotlib 패키지를 이용한 시각화

import seaborn as sns
import matplotlib.pyplot as plt # matpltlib 패키지 중에서 pyplot모듈을 plt로 불러온다.  

df=sns.load_dataset('penguins')


#산점도: 날개 길이와 몸무게의 관계
plt.scatter(df['flipper_length_mm'], df['body_mass_g']) #scatter()함수는 산점도를 나타내는 함수.
#그 안에 x축(날개의 길이), y축(몸무게) 정보를 입력한다.
plt.show() #==그래프를 출력하는 함수.



#바 형 그래프: 펭귄 종별 몸무게 차이
import seaborn as sns
import matplotlib.pyplot as plt

df=sns.load_dataset('penguins')

df_group = df.groupby('species')['body_mass_g'].mean().reset_index() #리셋인덱스==데이터프레임 형태로 나타내겠다.
plt.bar(x=df_group['species'], height=df_group['body_mass_g']) #bar()함수는 막대그래프를 그리는 함수
#그 안에 x축(그룹화한 종), y축(그룹 몸무게의 평균)
plt.show()




#히스토그램 - 몸무게의 분포
import seaborn as sns
import matplotlib.pyplot as plt

df=sns.load_dataset('penguins')

plt.rc('font', family = 'Malgun Gothic') #한글을 나타낼 수 있는 폰트로 변경한다.
plt.hist(df['body_mass_g'], bins=30) #히스토그램에 나타내고자 하는 열 입력, 히스토그램을 몇 개의 구간으로 나눌지 입력
plt.xlabel('Body Mass') #x축과 y축 레이블에 제목으로 표시할 말 입력.
plt.ylabel('Count')
plt.title('펭귄의 몸무게 분포')
plt.show()




#선 그래프
import matplotlib.pyplot as plt

import pandas as pd
df_unrate = pd.read_csv(
)  # 어디 사이트에서 제공하는 미국 실업자 데이터를 받아온다. read_csv()이용.

df_unrate.head() #---unrate는 unemployment rate의 줄임말!

df_unrate['DATE'] = pd.to_datetime(df_unrate['DATE']) #DATE열을 datetime 객체로 변환한다.

plt.plot(df_unrate['DATE'], df_unrate['VALUE']) #plot()함수는 선 그래프라는 뜻! 괄호 안에 x축 정보, y축 정보를 입력한다.
#여기서는 x축: date, y축: value

plt.show() #그래프 출력하기





#한 번에 여러 개의 그래프??== 하나의 figure(그림 그려지는 종이) 내에 여러개의 axes(그래프)그리기.
#크게 stateless API (객체지향, 정교) 방식과  stateful API(간단) 방식이 있다.

# 1. stateless 방법으로 그리기
import seaborn as sns
import matplotlib.pyplot as plt
df=sns.load_dataset('penguins')
plt.rc('font', family = 'Malgun Gothic') #(한글 폰트)

fig, axes = plt.subplots(2, 1, figsize=(10, 6))
#plt.subplots(figure 내에 "2행, 1열", figure의 가로 세로 길이는 10, 6이다.)

#그래프 1
axes[0].scatter(df['flipper_length_mm'], df['body_mass_g']) #산점도 그림.
axes[0].set_xlabel('날개 길이(mm)')
axes[0].set_ylabel('몸무게(g)')
axes[0].set_title('날개와 몸무게 간의 관계')

#그래프 2
axes[1].hist(df['body_mass_g'], bins=30) #히소토그램 그리기, bins==몇 개의 막대기?
axes[1].set_xlabel('Body Mass')
axes[1].set_ylabel('Count')
axes[1].set_title('펭귄의 몸무게 분포')


# 여백과 간격 조정
plt.subplots_adjust(left=0.1,
                    right=0.95,
                    bottom=0.1,
                    top=0.95,
                    wspace=0.5, #서브플롯들 사이의 가로 간격
                    hspace=0.5) #서브플롯들 사이의 세로 간격

plt.show()





# 2. Stateful방법을 사용해서 그리기

import seaborn as sns
import matplotlib.pyplot as plt
df=sns.load_dataset('penguins')
plt.rc('font', family = 'Malgun Gothic')

plt.figure(figsize=(10, 6)) #figure만들고 가로세로 길이 입력

#그래프 1
plt.subplot(2, 1, 1) #figure내에 만들 2행 1열의 axes 중 첫번째 axes를 그린다.
plt.scatter(df['flipper_length_mm'], df['body_mass_g'])
plt.xlabel('날개 길이(mm)')
plt.ylabel('몸무게(g)')
plt.title('날개와 몸무게 간의 관계')

#그래프 2
plt.subplot(2, 1, 2)
plt.hist(df['body_mass_g'], bins=30)
plt.xlabel('Body Mass')
plt.ylabel('Count')
plt.title('펭귄의 몸무게 분포')

# 여백 조정
plt.subplots_adjust(left=0.1,
                    right=0.95,
                    bottom=0.1,
                    top=0.95,
                    wspace=0.5,
                    hspace=0.5)

plt.show()

#apply() 메서드: 시리즈나 데이터프레임의 개별 원소에 함수를 적용할 수 있다.

for문보다 빠르다.

 

 

 


#1. 시리즈에 적용하기-----series.apply(함수)연습.

import seaborn as sns

df = sns.load_dataset('penguins')
bill_length_mm = df['bill_length_mm'] #펭귄 데이터에서 부리 길이 열만 선택하여 샘플 시리즈 객체를 만든다.

print(bill_length_mm.head())
 
 
 


import numpy as np

result = bill_length_mm.apply(np.sqrt) #해당 시리즈에 있는 원소들의 제곱근을 구한다. apply함수 안에 넘피 패키지-제곱근 만들기 함수를 넣어서 쓴 것임.
print(result.head())
 
 
 
 
 
 

# 새로운 함수= mm를 cm로 바꿔주는 함수.
import seaborn as sns

df = sns.load_dataset('penguins')
bill_length_mm = df['bill_length_mm']

def mm_to_cm(num):
    return num / 10

result_2 = bill_length_mm.apply(mm_to_cm)
print(result_2.head())
 
 
 




#2.데이터 프레임에 적용하기 -----열 또는 행 하나씩 분리하여 적용할 수 있음.
 
import seaborn as sns

df = sns.load_dataset('penguins')
bill_length_mm = df['bill_length_mm']

df_num = df[['bill_length_mm', 'bill_depth_mm', 'flipper_length_mm', 'body_mass_g']]
#먼저 펭귄 데이터셋에서 숫자로만 이뤄진 열을 선택함.
df_num.head()
 
 
 

#각 열에 함수 적용====같은 열에서 행 방향으로 내려가야 되니까 axis=0
print(df_num.apply(max)) # ==== df_num.apply(max, axis=0)
 

#각 행의 최댓값은? axis=1로 열 방향으로 진행하면서, 각 열의 값끼리 비교한다.
print(df_num.apply(max, axis=1))
print(df_num)
 
 
 
 



#새로운 함수= 각 열의 결측치?
 
import seaborn as sns
import pandas as pd
import numpy as np

df = sns.load_dataset('penguins')

df_num = df[['bill_length_mm', 'bill_depth_mm', 'flipper_length_mm', 'body_mass_g']]

def num_null(data):
    null_vec = pd.isnull(data) #isnull은 결측치면 True, 값이 있으면 False를 반환한다.
    null_count = np.sum(null_vec) #True에 해당하는 값이 더해져 결측치의 개수가 나옴.

    return null_count

print(df_num.apply(num_null)) #각 열에 해당 함수를 적용한다. (각 열 별로 결측치의 수를 세서 보여줌==행 방향으로 내려가야 함== axis=0)
 
#모든 열에 결측치가 두 개씩 있음을 확인할 수 있다.
 
 
 
 

#데이터 재구조화------ melt(), pivot_table(), stack(), unstack()


import seaborn as sns

df = sns.load_dataset('penguins')
print(df.head())
 
 
 
 

#melt():

id변수를 기준으로 원본 데이터프레임의 열 이름들을 variable 열에 넣고, 각 열에 있던 데이터는 value 열에 넣음.

 
print(df.melt(id_vars=['species', 'island', 'bill_length_mm']).head(10))
 
#id_vars에 입력한 열은 식별자 변수가 되고 나머지는 variable열에 하나씩 들어감.
 
 
 
 
 


#pivot_table():

인덱스, 칼럼, 밸류, aggfunc(데이터 집계 함수)를 입력해야 한다.

 
import seaborn as sns
df = sns.load_dataset('penguins')

df_pivot_1 = df.pivot_table(index='species',
                            columns='island',
                            values='bill_length_mm',
                            aggfunc=['mean', 'count']) #복수 조건은 리스트로 입력.
 

print(df_pivot_1) #펭귄 데이터의 species와 island별 bill_length의 평균값, 개체 수를 나타낸 표, 그 지역에 해당 종이 1마리도 안 살면 NaN으로 표시.

#인덱스, 칼럼, 밸류, aggfunc(데이터 집계 함수)는 각각 하나가 아닌 여러개를 입력할 수 있다.
 
 





#stack(): 열 인덱스를 행 인덱스로 바꿈.

#unstack(): 행 인덱스를 열 인덱스로 바꿈.


import seaborn as sns
df = sns.load_dataset('penguins')

df_pivot_4 = df.pivot_table(index=['species', 'sex'],
                            columns= 'island',
                            values='bill_length_mm',
                            aggfunc='mean')

print(df_pivot_4)
print(df_pivot_4.stack().to_frame()) #투프레임은 시리즈를 데이터프레임 형태로 변경하고 싶을 때 쓴다. 생략가능
print(df_pivot_4.unstack())  #행 인덱스인 female, male이 열 인덱스로 변경됨. species는 현재 기본인덱스라서 변경되지 않음.


#데이터프레임 합치기: pandas에서 concat(), merge(), join() 이용.

#1.concat(), 행 기준으로 합치기

import pandas as pd

df1 = pd.DataFrame({
    "A": ["A0", "A1", "A2","A3"],
    "B": ["B0", "B1", "B2", "B3"],
    "C": ["C0", "C1", "C2", "C3"],
    "D": ["D0", "D1", "D2", "D3"]
},
    index=[0, 1, 2, 3],
)  
#뭐 이렇게 비슷한 거 세 개를 한꺼번에 나오도록 합칠 수 있다. result = pd.concat([df1, df2, df3])이렇게 쓴 다음 print(result)하면 됨.
 
 
 
 
 

#열 이름이 다른데 concat하는 경우: 값이 없는 행은 NaN으로 채워짐
df4 = pd.DataFrame({
    "B": ["B2", "B3", "B6", "B7"],
    "D": ["D2", "D3", "D6", "D7"],
    "F": ["F2", "F3", "F6", "F7"]
},
    index=[2, 3, 6, 7]
)

result = pd.concat([df1, df4])

print(result)
 
 
 



#합칠 때 행 인덱스 초기화하기 : 인덱스가 그냥 0부터 차례대로 나오도록 바뀜
result = pd.concat([df1, df4], ignore_index=True)

print(result)
 
 
 



#2.concat(), 열 기준으로 합치기

import pandas as pd

df1 = pd.DataFrame({
    "A": ["A0", "A1", "A2","A3"],
    "B": ["B0", "B1", "B2", "B3"],
    "C": ["C0", "C1", "C2", "C3"],
    "D": ["D0", "D1", "D2", "D3"]
},
    index=[0, 1, 2, 3],
)  

df4 = pd.DataFrame({
    "B": ["B2", "B3", "B6", "B7"],
    "D": ["D2", "D3", "D6", "D7"],
    "F": ["F2", "F3", "F6", "F7"]
},
    index=[2, 3, 6, 7]
)
 

result = pd.concat([df1, df4], axis=1)   #axis=1을 입력하는 게 열 방향으로 하겠다는 의미이다.
print(result)
 
 

result = pd.concat([df1, df4], axis=1, join="inner") #조인=이너: 합집합이 아닌 교집합을 기준으로 함.
#== 행 인덱스가 겹치는 2, 3행만 출력 == NaN 값 없음.
print(result)
 
 
 
 


#데이터프레임+시리즈

s1 = pd.Series(["X0", "X1", "X2", "X3"], name="X")
result = pd.concat([df1, s1], axis=1)
print(result)


'''
 
merge함수(==조인인데 행 기준이 아니라 열 기준):
기준이 되는 열 또는 인덱스를 기준으로 합침(inner join, left/right join, outer join)
inner join: pd.merge(left쪽 데이터프레임 이름, right쪽 데이터프레임 이름, on = 'inner)
 
left join: pd.merge(left, right, on = "기준이 되는 열")
right join: pd.merge(left, right, on = '기준이 되는 열')
outer join: pd.merge(left, right, on = 'outer')
 
 
'''

# inner join: 양쪽 데이터프레임의 열의 교집합 부분을 반환.
 
#pd.merge(left, right, on="key")
left = pd.DataFrame({
    "key": ["K0", "k1", "k2", "K3"],
    "A": ["a0", "a1", "a2", "a3"],
    "B": ["b0", "b1", "b2". "b3"]
})

'''
 
 
left join: 레프트는 유지, 하이트가 합쳐짐.
 
 pd.merge(left, right, on="key", how='left')
 
right join은 그 반대
 
 pd.merge(left, right, on='key', how='right')
 
 
 
 
 
'''

#outer join: 합집합.
#reesult = pd.merge(left, right, on="key", how='outer')


#join함수==행 기준으로 dataframe 합침. join() 메서드는 디폴트로 left join을 사용한다.
 
 
 
 
import seaborn as sns

df=sns.load_dataset('mpg') #mpg는 연비. miles per gallon
print(df.head()) # 맨 위 5행을 출력
 
 
 
 


#인덱스 열을 네임으로 바꾸고 싶을 때.
 
df.set_index('name', inplace=True) #inplace=True는 원본 객체를 변경하겠다는 말이다.
 
 
 
 
 

#인덱스 정렬.
 
df.sort_index(inplace=True) # 이렇게 쓰면 index기준, 기본적으로 오름차순으로 정렬된다.

df.sort_index(inplace=True, ascending=False) #내림차순으로 하고 싶으면 ascending=False
 
 
 
 
 

#인덱스를 다시 원래대로 돌려놓기
 
df.reset_index(inplace=True)
df.head()


print(df.head()) 
 
 



#cylinders 열은 자동차의 실린더 개수를 의미한다. 어떤 값들이 있을까?
 
import seaborn as sns
df=sns.load_dataset('mpg')

print(df['cylinders'].unique())
 
 
 
 
 

# 실린더가 4인 조건을 만족하는 행만 출력
 
filter_bool = (df['cylinders'] ==4)
print(filter_bool.tail(10))
 
 
 
 
 

#행 인덱스에 위의 불리언 시리즈를 입력하면 해당 조건을 만족하는 행만 선택된다.
 
print(df.loc[filter_bool, ])  #쉼표 뒤에는 열 이름. 칸 비워놓는 건 모든 열을 출력하겠다는 의미
 
 
 
 


# 실린더 개수가 4개이면서 마력이 100이상인 데이터만 출력해 보자.
 
filter_bool_2 = (df['cylinders']== 4) & (df['horsepower']>=100)
print(df.loc[filter_bool_2,['cylinders', 'horsepower', 'name' ]])
 
 
 
 


#특정 이름을 가진 자동차의 데이터를 출력하고 싶을 때. or을 |로 나타낼 수 있음. 근데 너무 길다.
 
import seaborn as sns
df=sns.load_dataset('mpg')

filter_bool_3 = (df['name']== 'ford maverick') | (df['name']=='ford mustang ii')| (df['name']== 'chevrolet impala')
print(df.loc[filter_bool_3, ])
 
 
 
 
 

#더 간단한 버전.
# isin()메서드 내에 조건들을 리스트 형태로 입력하면 해당 값이 존재=True, 존재x=False로 반환한다.

filter_isin = df['name'].isin(['ford maverick', 'ford mustang ii', 'chevrolet impala'])
print(df.loc[filter_isin, ['name', 'weight', 'model_year']])
 
 
 
 



#특정 열의 데이터별로 정렬해보자. 마력이 같은 자동차들끼리 묶어서 작은 순서대로 정렬하기.
 
print(df.loc[filter_isin, ].sort_values('horsepower'))
#여기서도 내림차순을 하려면 ascending=False입력하면 내림차순 됨.
 





#새로운 열 만들기: 무게 대비 연비인 mpg/wt를 나타내는 ratio열을 만들어 보자.
 
import seaborn as sns
df=sns.load_dataset('mpg')

df['ratio'] = (df['mpg']/ df['weight']) * 100
print(df.head())
 
 
 
 


#특정 열의 조건을 기반으로 새로운 열 만들기: NumPy 패키지의 where()함수를 사용한다.
 
import pandas as pd
import numpy as np

num = pd.Series([-2, -1, 1, 2])
print(np.where(num>=0)) #num이라는 시리즈에는 -2부터 2까지의 정수가 있는데, 그 중 0보다 크거나 0과 같은 0, 1, 2인 지점의 인덱스만 반환함.

np.where(num >=0, '양수', '음수') #num이 0보다 크거나 0과 같으면 '양수'를 부여, 그렇지 않으면 '음수'를 부여한다.
print(np.where(num >=0, '양수', '음수'))
 
 
 
 



#위의 내용을 응용해서  horsepower를 세 단계로 구분하는 열을 만들어 보자.
 
import seaborn as sns
df=sns.load_dataset('mpg')
import numpy as np

df['horse_power_div']=np.where(
    df['horsepower'] <100, '100 미만',
    np.where((df['horsepower'] >=100) & (df['horsepower'] <200), '100이상',
    np.where(df['horsepower'] >=200, '200이상', '기타')))
print(df.head())
 
 

데이터프레임(dataframe) : 2차원 배열로 각 열이 하나의 시리즈로 구성되어 있다.

 


# 원소의 개수가 동일한 1차원 배열(시리즈)가 모여서 데이터프레임이 된다.
 
import pandas as pd

dict_data = {'col1': [1, 2, 3], 'col2': [4, 5, 6], 'col3': [7, 8, 9]} #각 쌍에 값이 3개씩 들어 있는 딕셔너리 만들기
df = pd.DataFrame(dict_data)

print(df)
 
결과:
   col1  col2  col3
0     1     4     7
1     2     5     8
2     3     6     9
 
 
print(type(df))
 
결과: <class 'pandas.core.frame.DataFrame'>
 
 
 
 
 
 


# 리스트를 통해서 데이터프레임 만들기.

df2 = pd.DataFrame([1,2,3], [4,5,6], [7,8,9])
print(df2) #--첫번째랑 같은 결과. 열 이름이 자동으로 0, 1, 2로 할당되었다는 점만 빼고.


#행 이름, 열 이름을 지정한 리스트로 데이터프레임 만들기

df3 = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9]],
                    index = ['index1', 'index2', 'index3'],
                    columns=['col1', 'col2', 'col3'])
print(df3)
 
 
 
 
 
 
 
 


#행 이름, 열 이름 변경하기

df3.index = ['행1', '행2', '행3']
df3.column = ['열1', '열2', '열3']

print(df3)

df3.rename(index={'행 1' : '첫 번째 행'}, inplace=True)

pandas 패키지는

1차원 배열인 series와 
행과 열로 이루어진 2차원 배열인 dataframe을 통해 데이터 분석을 수행한다.
 
 
# 1. 시리즈(series) : 1차원 배열, 딕셔녀리와 비슷하게 인덱스와 값이 일대일 대응함.

import pandas as pd

dict_data = {'a':1, 'b':2, 'c':3} #딕셔너리를 먼저 만듦
series = pd.Series(dict_data) #Series 함수에 그 딕셔너리를 입력하면 시리즈 객체로 변환시켜 줌.



print(series)
결과:
a    1
b    2
c    3
dtype: int64




print(series.index)
#딕셔너리의 키==시리즈의 인덱스


결과:
Index(['a', 'b', 'c'], dtype='object')



print(series.values)
#딕셔너리의 밸류==시리즈의 값


결과:
[1 2 3]






# 딕셔너리 말고 리스트로 만들기
(위치를 나타내는 인덱스는 자동으로 지정되는데 0부터 시작한다.)

import pandas as pd

list_data = ['a', 'b', 'c']
series_2 = pd.Series(list_data)

print(series_2)

결과:
0    a
1    b
2    c
dtype: object




print(series_2.index)

결과:
RangeIndex(start=0, stop=3, step=1)




print(series_2.values)

결과:
['a' 'b' 'c']








#리스트를 통헤 시리즈를 만들고
index옵션에 인덱스 이름을 직접 입력하기

import pandas as pd

list_data = ['a', 'b', 'c']
series_3 = pd.Series(list_data, index=['index1', 'index2', 'index3'])

print(series_3)

결과:
index1    a
index2    b
index3    c
dtype: object






#원소 선택하기


import pandas as pd
capital = pd.Series({'Korea': 'Seoul',
                     'Japan': 'Tokyo',
                     'China': 'Beijing',
                     'India': 'New Deli',
                     'Taiwan': 'Taipei',
                     'Singapore': 'Singapore'
                     })

print(capital)

결과:
Korea            Seoul
Japan            Tokyo
China          Beijing
India         New Deli
Taiwan          Taipei
Singapore    Singapore
dtype: object




print(capital['Korea'])

결과:
Seoul




print(capital[['Korea', 'Taiwan']])
#값을 찾고 싶은 인덱스를 리스트 안에 입력하면 이에 해당하는 모든 원소가 선택된다.

결과:
Korea      Seoul
Taiwan    Taipei
dtype: object




print(capital[0])
결과: Seoul




print(capital[[0, 3]])
#이것도 리스트안의리스트에 적힌 모든 원소(코리아--서울, 인디아--뉴델리)가 출력된다.

결과:
Korea       Seoul
India    New Deli
dtype: object



print(capital[0:3])
#슬라이싱. 인덱스 0 이상, 3"미만"인 값들이 출력된다.

결과:
Korea      Seoul
Japan      Tokyo
China    Beijing
dtype: object






#시리즈의 사칙연산
series_1 = pd.Series([1,2,3])
series_2 = pd.Series([4,5,6])

print(series_1 + series_2)
결과:
0    5
1    7
2    9
dtype: int64




print(series_1*2)
결과:
0    2
1    4
2    6
dtype: int64

#코드를 일시정지하기

import datetime
import time

for i in range(3): #0부터 2까지 for문 내에서 i와 현재 시간을 출력함.

    print(i)
    print(datetime.datetime.now())

    print('---------------------')

    time.sleep(2) #루프 당 2초의 일시정지를 줌.

 

 

 

 

 

 

# for 문 진행 정도 확인하기 --- tqdm()


import time
from tqdm import tqdm

for i in tqdm(range(10)):

    time.sleep(0.1) #숫자가 커질수록 더디게 진행??
   
   
   
   
   

    

#매개변수가 여러 개인 함수에서 디폴트값 설정


def divide(x, n=2):

    res = x / n
    return (res)

print(divide(3))
#두번째 매개변수는 자동으로 2로 입력됨.---3나누기2= 1.5 출력.


 

 

 

# 람다 함수: return 없어도 결괏값을 반환한다.

# (함수명) = lambda 매개변수1, 매개변수2, ...:statement


divide_lam = lambda x, n: x/n

divide_lam(6,3) #==2.0

#날짜와 시간 구하기

import datetime

 

var= datetime.datetime.now()

print(var)

결과 : 2023-12-02 12:23:58.974140

 

 

 

print(var.year)
결과: 2023
 
print(var.weekday()) #요일을 숫자로, 월요일이 0
결과: 5

print(var.date(), var.time())
결과: 2023-12-02 12:23:58.974140

print(var.strftime('%Y년 %b월 %j일 '))
결과: 2023년 Dec월 336일
 
 
"""
%y(소문자): 연도 뒤 두 자리만
%B(December전체), %b(Dec축약) : 영어(Locale) 월 표현
%j: 연중 일
"""

print(var.strftime("%H시 %M분 %S초 %X"))
결과: 12시 23분 58초 12:23:58
 
 
"""
%ㅣ: 12시간으로 시간표시
%P: 오전 오후 표시
%f: 마이크로초
%W: 연중 몇 번째 주인지(월요일 시작)
%U: 연중 몇 번째 주인지(일요일 시작)
%c: 영어로(Locale) 요일, 월, 날짜, 시간 나오는 거
%x: 영어로(Locale) 날짜
%X: 한글로(Locale) 시간
"""

 

 

 

#날짜와 시간 연산하기 -- 날짜와 초 단위

 
import datetime

dt1= datetime.datetime(2022, 12, 31)
dt2= datetime.datetime.now()

td= dt2 - dt1

print(td)
결과: 336 days, 12:23:58.974140
 
print(dt1+datetime.timedelta(days=1)) #1일 더하기
결과: 2023-01-01 00:00:00


 

 

#월 단위로 연산하기

 
import datetime
from dateutil.relativedelta import relativedelta
dt1= datetime.datetime(2022, 12, 31)

print(dt1+relativedelta(months=1))
결과: 2023-01-31 00:00:00


 

+ Recent posts