>>> import pandas as pd
>>> import numpy as np
>>> data = pd.Series([1., -999., 2., -999., -1000., 3.])
data
>>> data.replace([-999, -1000], np.nan)
>>> np.where(data <= -999, np.nan, data)
>>> df = pd.DataFrame({'A' : ['a5', 'a6'], 'B' : ['b5', 'b6'],
'C' : ['c5', 'c6']})
df
>>> new_row = pd.DataFrame([['aaa', 'bbb', 'ccc']], columns = df.columns)
new_row
>>> pd.concat([df, new_row])
>>> pd.concat([df, new_row], ignore_index = True)
>>> df = pd.DataFrame({'A' : ['a1', 'a2', 'a3', 'a4'],
'B' : ['b1', 'b2', 'b3', 'b4'],
'C' : [1, 2, 3, 4]})
df
>>> df.melt(id_vars = ['A'], value_vars = ['B','C'])
>>> df.melt(id_vars = ['A'])
>>> df.melt(['A'])
>>> df.melt(['A'], ['B', 'C'], var_name = 'New')
>>> np.random.seed(1234)
>>> a = pd.DataFrame(np.random.randn(1000, 5))
a
>>> a[(np.abs(a) > 3).any(1)]
>>> a[(np.abs(a) > 3)].any(axis = 1)
>>> a[(np.abs(a) > 3)].any(axis = 1).sum()
>>> import pydataset
>>> movies = pydataset.data('movies')
movies
>>> movies.info()
>>> movies[['title', 'year', 'length']] #또는 movies.iloc[:, :3]
>>> m = movies[['title', 'year', 'length']]
m
>>> m['length']
>>> bins = [1, 60, 100, 180]
pd.cut(m['length'], bins, labels = ['short', 'mid', 'long'])
>>> movies['time'] = pd.cut(m['length'], bins, labels = ['short', 'mid', 'long'])
movies.head()
>>> df = pd.read_excel('excel_exam.xlsx')
df
>>> df.melt(id_vars = 'class', value_vars = ['math', 'science'],
var_name = '과목', value_name = '점수')
>>> df = pd.DataFrame({'key': ['foo', 'bar', 'baz'],
'A': [1, 2, 3],
'B': [4, 5, 6],
'C': [7, 8, 9]})
df
#melt
>>> df.melt(id_vars = ['key'], value_vars = ['A','B'])
>>> df1 = df.melt(id_vars = ['key'], value_vars = ['A','B','C'])
df1[:4]
#pivot
>>> df1.pivot(index = 'key', columns = 'variable', values = 'value')
>>> df1.pivot(columns = 'variable', values = 'value')
>>> df1.pivot(index = 'key', columns = 'variable',
values = 'value').reset_index()
https://raw.githubusercontent.com/wesm/pydata-book/3rd-edition/examples/macrodata.csv
>>> data = pd.read_csv('macrodata.csv')
data.head()
>>> periods = pd.PeriodIndex(year=data.year, quarter=data.quarter,
name='date')
columns = pd.Index(['realgdp', 'infl', 'unemp'], name='item')
data = data.reindex(columns=columns)
data.index = periods.to_timestamp('D', 'end')
ldata = data.stack().reset_index().rename(columns={0: 'value'})
>>> ldata #긴 형식의 데이터이다
>>> ldata.pivot(index = 'date', columns = 'item', values = 'value')
>>> ldata['value2'] = np.random.randn(len(ldata))
ldata
>>> ldata.pivot(index = 'date', columns = 'item')
>>> ldata.pivot(index = 'date', columns = 'item',
values = ['value', 'value2'])[:4]
>>> ldata.pivot(index = 'date', columns = 'item',
values = ['value', 'value2']).reset_index()[:4]
>>> ldata.set_index(['date', 'item'])
>>> ldata.set_index(['date', 'item']).unstack('item')
matplotlib에서 그래프는 Figure 객체 내에 존재한다
그래프를 위한 새로운 figure는 'plt.figure' 를 입력하여 생성할 수 있다
빈 figure 로는 그래프를 그릴 수 없으므로, 'add_subplot' 을 사용해서 최소 하나 이상의 'subplots'를 생성해야 한다
>>> fig.add_subplot(2,2,1)
#figure의 크기가 2x2 이고, 4개의 subplot 중에서 첫번째를 선택한다는 의미
눈금, 라벨, 범례
pyplot 인터페이스를 사용해서 xlim, xticks, xticklabels 와 같은 메서드로 표의 범위를 지정하거나 눈금 위치, 눈금 이름 등을 조절할 수 있다
범례 추가는 plt.legend 를 이용해서 할 수 있다 (축에 대한 범례 : ax.legend)
도형 추가하기
matplotlib 은 일반적인 도형을 표현하기 위한 patches 라는 객체를 제공한다
전체 모음은 matplotlib.patches 에 있다
그래프를 파일로 저장하기
활성화된 figure 는 plt.savefig 메서드를 이용해서 저장할 수 있다
>>> plt.savefig('figpath.png', dpi = 400, bbox_inches = 'tight')
>>> plt.rc('figure', figsize = (10,10))
Series와 DataFrame은 둘다 plot 메서드를 이용해 다양한 형태의 그래프를 생성할 수 있다
기본적으로 plot 메서드는 선그래프를 생성한다
>>> import matplotlib.pyplot as plt
>>> import seaborn as sns
#Series
>>> s = pd.Series(np.random.randn(10).cumsum(), index = np.arange(0,100,10))
s
>>> s.plot()
Series 객체의 색인은 matplotlib에서 그래프를 생성할 때 'x축' 으로 해석되며 'use_index = False' 옵션을 넘겨서 색인이 그래프의 축으로 사용되는 것을 막을 수도 있다
x축의 눈금과 한계는 'xticks'와 'xlim' 옵션으로 조절할 수 있다 (y축도 마찬가지)
#DataFrame
>>> df = pd.DataFrame(np.random.randn(10,4).cumsum(0),
columns=['A', 'B', 'C', 'D'],
index=np.arange(0, 100, 10))
df
>>> df.plot()
>>> df.plot(kind = 'bar')
df.plot(kind = 'hist')
df.plot(kind = 'box')
df.plot(kind = 'kde')
누적 막대 그래프는 'stacked=True' 옵션을 사용해서 생성할 수 있는데, 각 로우의 값들이 하나의 막대에 누적되어 출력된다
>>> df = pd.DataFrame(np.random.randn(10,4).cumsum(0),
columns=['A', 'B', 'C', 'D'],
index=np.arange(0, 100, 10))
>>> df.plot.bar()
df.plot.barh()
>>> tips = pydataset.data('tips')
tips
>>> pd.crosstab(tips['day'], tips['size'])
>>> party_counts = pd.crosstab(tips['day'], tips['size'])
#각 로우의 합이 1이 되도록 정규화
>>> party_counts.div(party_counts.sum(axis = 1), axis = 0)
>>> party_pcts = party_counts.div(party_counts.sum(axis = 1), axis = 0)
>>> party_pcts.plot.bar(rot = 0)
party_pcts.plot.barh()
파티의 규모가 주말에 커지는 경향이 있음을 알 수 있다
그래프를 그리기 전에 요약을 해야하는 데이터는 seaborn 패키지를 이용하면 간단하게 처리할 수 있다
>>> tips['tip_pct'] = tips['tip']/(tips['total_bill'] - tips['tip'])
tips.head()
>>> tips['tip_pct'].plot.bar()
>>> sns.barplot(data = tips, x = 'day', y = 'tip_pct')
>>> sns.barplot(data = tips, x = 'tip_pct', y = 'day', orient = 'h')
seaborn 플로팅 함수의 data 인자는 pandas의 DataFrame을 받는다
막대 그래프 위에 덧그려진 검은 선은 95%의 신뢰구간을 나타낸다
>>> tips['tip_pct'].plot.hist(bins = 50)
seaborn 라이브러리의 distplot 메서드를 이용해서 히스토그램과 밀도 그래프를 한번에 손 쉽게 그릴 수 있다
#두개의 다른 표준정규분포로 이루어진 양봉분포
>>> comp1 = np.random.normal(0,1,size =200)
>>> comp2 = np.random.normal(10,2,size =200)
>>> values = pd.Series(np.concatenate([comp1, comp2]))
>>> sns.distplot(values, bins = 100, color = 'k')
다양한 범주형 값을 가지는 데이터를 시각화하는 방법
seaborn은 factorplot 이라는 내장 함수를 제공하여 다양한 면을 나타내는 그래프를 쉽게 그릴 수 있게 해준다
>>> sns.factorplot(data = tips[tips.tip_pct < 0.5], x = 'tip_pct', y = 'day', kind = 'box')
>>> sns.factorplot(data = tips[tips.tip_pct < 1], x = 'day', y = 'tip_pct', hue = 'time', col = 'smoker', kind = 'bar')
>>> sns.catplot(data = tips[tips.tip_pct < 0.5], x = 'tip_pct', y = 'day', kind = 'box')
>>> tips[:5]
>>> tips.pivot(index = 'total_bill', columns = 'day', values = 'tip_pct')
>>> df = pd.read_excel('excel_exam.xlsx')
df
>>> melted = df.melt(id_vars = 'class', value_vars = ['math', 'science', 'english'], var_name = '과목', value_name = '점수')
melted
>>> melted.pivot(index = 'class', columns = '과목', values = '점수')
데이터 내에 같은 값을 가지는(같은 값이 있어 겹치는) 칼럼을 인덱스로 설정하려 해서 에러
melt 한 후 pivot 으로 다시 되돌리는 것이 안될 수도 있다
>>> pip install plotly
>>> import plotly.express as px
>>> g = px.data.gapminder()
g[:3]
>>> g.info() #RangeIndex: 1704 entries, 0 to 1703 -> 1704개의 로우가 있다
>>> pd.pivot(data = g, index = 'country', columns = 'continent',
values = 'year') #같은 에러가 발생한다
#year, country, gdpPercap 을 이용하여 pivot 해 봅시다
>>> pd.pivot(data = g, index = 'year', columns = 'country', values = 'gdpPercap')
>>> pd.pivot(data = g, index = 'year', columns = 'country', values = ['gdpPercap', 'pop'])
>>> df1 = pd.pivot(data = g, index = 'year', columns = 'country', values = 'gdpPercap')
df1
>>> df1.reset_index(inplace = True)
df1
>>> df1.columns[1:] #df1의 column의 개수 확인
>>> df1.melt(id_vars = 'year', value_vars = df1.columns[1:], var_name = 'country', value_name = 'gdpPercap')
① Series, DataFrame 같은 pandas 객체나, 다른 객체에 들어있는 데이터를 하나 이상의 '키' 를 기준으로 '분리' 한다
(하나의 축(로우 또는 칼럼)을 기준으로 분리할 수 있다)
② 함수를 각 그룹에 '적용' 시켜 새로운 값을 얻어낸다
③ 함수를 적용한 결과를 하나의 객체로 '결합' 한다
>>> df = pd.DataFrame({'key1': ['a', 'a', 'b',' b', 'a'],
'key2': ['one', 'two', 'one', 'two', 'one'],
'data1': np.random.randn(5),
'data2': np.random.randn(5)})
df
#key1과 key2로 그룹짓고, min() 구하기
>>> df.groupby(['key1', 'key2']).min()
>>> df.groupby(['key1', 'key2']).mean()
>>> df.groupby(['key1', 'key2'])[['data2']].mean()
배열로부터 스칼라값을 만들어내는 모든 데이터 변환 작업
mean, count, min, sum 등을 이용해서 스칼라 값을 구할 수 있다
직접 만든 함수를 사용할 수도 있다
>>> df.groupby(['key1', 'key2']).quantile()
>>> df.groupby(['key1', 'key2'])[['data1']].quantile()
>>> def peak_to_peak(arr):
return arr.max() - arr.min()
#.max() 와 .min() 은 전체 데이터 중에 max값과 min값 '하나'를 돌려준다
>>> df.groupby(['key1']).min()
>>> df.groupby(['key1']).apply(min)
>>> df.groupby(['key1']).apply(peak_to_peak)
#apply 로는 사용자 정의 함수를 적용할 수 없다
>>> df.groupby(['key1']).agg(peak_to_peak)
>>> list(df.groupby(['key1']))
>>> tips = pydataset.data('tips')
tips
>>> tips['tip_pct'] = tips['tip'] / tips['total_bill']
tips.head()
>>> grouped = tips.groupby(['day', 'smoker'])
>>> grouped.agg({'tip' : np.max, 'size' : sum})
>>> grouped.agg(['count', 'mean', 'max'])
#함수 이름을 칼럼으로 하는 DataFrame 을 얻게 된다
>>> gg = grouped.agg(['count', 'mean', 'max'])
>>> gg.agg([('ct', 'count'), ('mn', 'mean'), ('mx', 'max')])
apply 메서드는 객체를 여러 조각으로 나누고, 전달된 함수를 각 조각에 일괄 적용한 후 이를 다시 합친다
#그룹별 상위 5개의 tip_pct 값을 구해보자
>>> tips
>>> def top(df, n=5, column = 'tip_pct'):
return df.sort_values(by = column)[-n:]
>>> top(tips)
>>> top(tips, n=10)
>>> def top(df, n=5, column = 'tip_pct'):
return df.sort_values(by=column, ascending = False)[:n]
>>> top(tips)
>>> tips.groupby(['day', 'smoker']).apply(top)
#apply 메서드로 넘길 함수가 추가적인 인자를 받는다면 함수 이름 뒤에 붙여서 넘겨준다
>>> tips.groupby(['day', 'smoker']).apply(top, n=2)
>>> tips.groupby(['day', 'smoker']).apply(top, n=2, column = 'tip')
>>> tips['tip']
>>> pd.cut(tips['tip'], 4)
#균등한 간격의 4그룹으로 cut -> dtype는 'category', Categories는 '4'
#cut 에서 반환된 Categorical 객체는 바로 groupby로 넘길 수 있다
>>> grouping = pd.cut(tips['tip'], 4)
>>> grouped1 = tips.groupby(grouping)
>>> list(grouped1)
>>> grouped1.apply(top)
>>> grouped1.apply(top, n=2)
>>> def get_stats(group):
return {'min' : group.min(), 'max' : group.max(),
'count' : group.count(), 'mean' : group.mean()}
>>> grouped1.agg(get_stats)
>>> grouped1.apply(get_stats)
>>> grouped1 = tips['tip'].groupby(grouping)
grouped1.apply(get_stats).unstack()
>>> def test(a, b, c=3):
return a + b+ c
>>> test(a=1, b=2, c=4)
7
>>> d = {'a' : 1, 'b' : 2, 'c' : 4}
test(**d) # ** : 입력되는 값이 dictionary 라는 의미
7
>>> s = pd.Series(np.random.randn(6))
s
>>> s[::2]
>>> s[::2] = np.nan
s
>>> s.fillna(s.mean())
>>> states = ['Ohio', 'New York', 'Vermont', 'Florida', 'Oregon', 'Nevada', 'California', 'Idaho']
>>> group_key = ['East'] * 4 + ['West'] * 4
group_key
#['East'] * 4 는 ['East'] 리스트 안에 있는 네 벌의 원소를 이어붙인다
>>> data = pd.Series(np.random.randn(8), index = states)
data
>>> data[['Vermont', 'Nevada', 'Idaho']] = np.nan
data
>>> list(data.groupby(group_key))
#data가 'East'와 'West'라는 그룹 2개로 나뉘어진 것을 볼 수 있다
>>> data.groupby(group_key).mean()
#East와 West 그룹 각각에 mean() 함수 적용
#누락된 값에 각 그룹의 평균값으로 채운다
>>> data.groupby(group_key).apply(lambda g: g.fillna(g.mean()))
대용량의 데이터를 다른 애플리케이션에서 사용하기 위해 랜덤 표본을 뽑아낸다고 하자.
Series의 sample 메서드를 사용하자
>>> suits = ['H','S','C','D']
card_val = (list(range(1, 11)) + [10] *3) *4
base_names = ['A'] + list(range(2, 11)) + ['J', 'K', 'Q']
>>> card_val
>>> base_names
>>> cards = []
for suit in ['H','S','C','D']:
cards.extend(str(num) + suit for num in base_names)
>>> cards
>>> deck = pd.Series(card_val, index = cards)
deck
#5장의 코드 뽑기
>>> def draw(deck, n=5):
return deck.sample(n)
>>> draw(deck)
#각 세트(H, S, C, D) 별로 2장의 카드를 무작위로 뽑기
#세트는 각 카드 이름의 마지막 글자에 해당된다 -> card[-1]
>>> deck.groupby(lambda card: card[-1]).apply(draw, n=2)
>>> deck.groupby(lambda card: card[-1], group_keys = False).apply(draw, n=2)