[데이터 분석] Python 라이브러리 - Pandas, Matplotlib, Numpy 10분만에 배우기
Python에서 데이터 분석을 위한 라이브러리 Pandas, Matplotlib, Numpy를 10분만에 익히는 방법
python에서 데이터 분석을 하기 위해서는 주로 사용하는 라이브러리가 있습니다. pandas, matplotlib, numpy입니다. 패키지들을 이용하는 이유는 데이터 분석을 용이하게 할 수 있도록, matrix연산과 시각화를 지원합니다. pandas는 DataFrame, Series의 데이터 객체를 이용해서 데이터를 쉽게 가공을 할 수 있습니다. 더나아가 평균, 분산, 최대, 최소 등을 쉽게 연산할 수 있습니다. 그 외에도 데이터 변수 사이에 연관성, 그룹, 선택, 조인 등의 다양한 함수를 통해 matrix를 효율적으로 쉽게 가공 할 수 있습니다. matplotlib은 데이터의 분포 및 패턴을 확인하기 위한 시각화 용도로 사용이 됩니다. 아래 예제를 통해 데이터 분석에 기본이 되는 함수를 익혀보도록 하겠습니다.
10 Minutes to pandas
In [273]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
Object Creation
In [274]:
s = pd.Series([1,3,5,np.nan,6,8])
In [4]:
s
Out[4]:
0 1.0
1 3.0
2 5.0
3 NaN
4 6.0
5 8.0
dtype: float64
In [5]:
# numpy array를 이용해 DataFrame 생성하기
dates = pd.date_range('20160620', periods=6)
dates
Out[5]:
DatetimeIndex(['2016-06-20', '2016-06-21', '2016-06-22', '2016-06-23',
'2016-06-24', '2016-06-25'],
dtype='datetime64[ns]', freq='D')
In [6]:
# 위에서 생성한 dates를 index로 생성하는 방법, (row x col)
df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD'))
df
Out[6]:
A | B | C | D | |
---|---|---|---|---|
2016-06-20 | 0.109326 | 0.149287 | 0.308792 | 0.009975 |
2016-06-21 | 0.548566 | 2.039298 | -0.389184 | 0.310511 |
2016-06-22 | -0.025059 | 0.410800 | 1.193115 | -1.306679 |
2016-06-23 | -1.017573 | 0.257004 | 0.825450 | 2.935268 |
2016-06-24 | 0.894756 | -0.973764 | 0.100148 | 0.285566 |
2016-06-25 | 0.071252 | 0.696173 | 1.371591 | 0.332136 |
In [7]:
# dict의 형태를 DataFrame으로 생성하는 방법.
df2 = pd.DataFrame({ 'A' : 1.,
'B' : pd.Timestamp('20130102'),
'C' : pd.Series(1,index=list(range(4)),dtype='float32'),
'D' : np.array([3] * 4,dtype='int32'),
'E' : pd.Categorical(["test","train","test","train"]),
'F' : 'foo' })
df2
Out[7]:
A | B | C | D | E | F | |
---|---|---|---|---|---|---|
0 | 1.0 | 2013-01-02 | 1.0 | 3 | test | foo |
1 | 1.0 | 2013-01-02 | 1.0 | 3 | train | foo |
2 | 1.0 | 2013-01-02 | 1.0 | 3 | test | foo |
3 | 1.0 | 2013-01-02 | 1.0 | 3 | train | foo |
In [8]:
# DataFrame의 datatype확인하는 방법
df2.dtypes
Out[8]:
A float64 B datetime64[ns] C float32 D int32 E category F object dtype: object
In [9]:
# Viewing Data
In [10]:
# DataFrame의 top N을 보는 방법 df.head(N)
df.head()
Out[10]:
A | B | C | D | |
---|---|---|---|---|
2016-06-20 | 0.109326 | 0.149287 | 0.308792 | 0.009975 |
2016-06-21 | 0.548566 | 2.039298 | -0.389184 | 0.310511 |
2016-06-22 | -0.025059 | 0.410800 | 1.193115 | -1.306679 |
2016-06-23 | -1.017573 | 0.257004 | 0.825450 | 2.935268 |
2016-06-24 | 0.894756 | -0.973764 | 0.100148 | 0.285566 |
In [11]:
# DataFrame의 bottom N을 보는 방법 df.tail(N)
df.tail(3)
Out[11]:
A | B | C | D | |
---|---|---|---|---|
2016-06-23 | -1.017573 | 0.257004 | 0.825450 | 2.935268 |
2016-06-24 | 0.894756 | -0.973764 | 0.100148 | 0.285566 |
2016-06-25 | 0.071252 | 0.696173 | 1.371591 | 0.332136 |
In [12]:
df.index
Out[12]:
DatetimeIndex(['2016-06-20', '2016-06-21', '2016-06-22', '2016-06-23',
'2016-06-24', '2016-06-25'],
dtype='datetime64[ns]', freq='D')
In [13]:
df.columns
Out[13]:
Index([u'A', u'B', u'C', u'D'], dtype='object')
In [23]:
df.values
Out[23]:
array([[-0.55438059, 0.41257123, 0.13468592, -0.30762167],
[ 0.52580499, -0.35814994, 1.2923575 , 1.12533021],
[-0.73907553, -0.12261106, -0.15062314, -0.61562674],
[ 1.02592656, -0.77207127, -0.45549946, -0.93190737],
[ 0.59770076, 0.06347513, -1.00554327, 0.98352547],
[-0.21020512, -1.26250553, 0.39272935, 0.60436413]])
In [24]:
df.describe()
Out[24]:
A | B | C | D | |
---|---|---|---|---|
count | 6.000000 | 6.000000 | 6.000000 | 6.000000 |
mean | 0.107629 | -0.339882 | 0.034684 | 0.143011 |
std | 0.709154 | 0.602403 | 0.784427 | 0.873878 |
min | -0.739076 | -1.262506 | -1.005543 | -0.931907 |
25% | -0.468337 | -0.668591 | -0.379280 | -0.538625 |
50% | 0.157800 | -0.240380 | -0.007969 | 0.148371 |
75% | 0.579727 | 0.016954 | 0.328218 | 0.888735 |
max | 1.025927 | 0.412571 | 1.292358 | 1.125330 |
In [25]:
# transposing
df.T
Out[25]:
2016-06-20 00:00:00 | 2016-06-21 00:00:00 | 2016-06-22 00:00:00 | 2016-06-23 00:00:00 | 2016-06-24 00:00:00 | 2016-06-25 00:00:00 | |
---|---|---|---|---|---|---|
A | -0.554381 | 0.525805 | -0.739076 | 1.025927 | 0.597701 | -0.210205 |
B | 0.412571 | -0.358150 | -0.122611 | -0.772071 | 0.063475 | -1.262506 |
C | 0.134686 | 1.292358 | -0.150623 | -0.455499 | -1.005543 | 0.392729 |
D | -0.307622 | 1.125330 | -0.615627 | -0.931907 | 0.983525 | 0.604364 |
In [36]:
# axis의 개념은 (0,0)을 기준으로 0=down, 1=across를 의미한다. 풀어 말하면
# axis=0은 각 apply a method down each column,row의 labels를 나타낸다 (index)
# axis=1은 각 apply a method across each row, column labels
df.sort_index(axis=1, ascending=False) # column의 값으로 정렬
Out[36]:
D | C | B | A | |
---|---|---|---|---|
2016-06-20 | -0.307622 | 0.134686 | 0.412571 | -0.554381 |
2016-06-21 | 1.125330 | 1.292358 | -0.358150 | 0.525805 |
2016-06-22 | -0.615627 | -0.150623 | -0.122611 | -0.739076 |
2016-06-23 | -0.931907 | -0.455499 | -0.772071 | 1.025927 |
2016-06-24 | 0.983525 | -1.005543 | 0.063475 | 0.597701 |
2016-06-25 | 0.604364 | 0.392729 | -1.262506 | -0.210205 |
In [ ]:
df.sort_index(axis=0, ascending=False) # row의 값으로 정렬
In [29]:
df.sort_values(by='B')
Out[29]:
A | B | C | D | |
---|---|---|---|---|
2016-06-25 | -0.210205 | -1.262506 | 0.392729 | 0.604364 |
2016-06-23 | 1.025927 | -0.772071 | -0.455499 | -0.931907 |
2016-06-21 | 0.525805 | -0.358150 | 1.292358 | 1.125330 |
2016-06-22 | -0.739076 | -0.122611 | -0.150623 | -0.615627 |
2016-06-24 | 0.597701 | 0.063475 | -1.005543 | 0.983525 |
2016-06-20 | -0.554381 | 0.412571 | 0.134686 | -0.307622 |
Selection
Getting
In [38]:
# getting
df['A']
Out[38]:
2016-06-20 -0.554381
2016-06-21 0.525805
2016-06-22 -0.739076
2016-06-23 1.025927
2016-06-24 0.597701
2016-06-25 -0.210205
Freq: D, Name: A, dtype: float64
In [39]:
df[1:3]
Out[39]:
A | B | C | D | |
---|---|---|---|---|
2016-06-20 | -0.554381 | 0.412571 | 0.134686 | -0.307622 |
2016-06-21 | 0.525805 | -0.358150 | 1.292358 | 1.125330 |
2016-06-22 | -0.739076 | -0.122611 | -0.150623 | -0.615627 |
Selection by label
In [41]:
# selection by label
df.loc[dates[0]]
Out[41]:
A -0.554381
B 0.412571
C 0.134686
D -0.307622
Name: 2016-06-20 00:00:00, dtype: float64
In [44]:
# : 는 row의 전체 범위를 의미한다.전체의 row에서 ['A','B'] column을 선택
df.loc[:,['A','B']]
Out[44]:
A | B | |
---|---|---|
2016-06-20 | -0.554381 | 0.412571 |
2016-06-21 | 0.525805 | -0.358150 |
2016-06-22 | -0.739076 | -0.122611 |
2016-06-23 | 1.025927 | -0.772071 |
2016-06-24 | 0.597701 | 0.063475 |
2016-06-25 | -0.210205 | -1.262506 |
In [55]:
# '20160620':'20160623 까지의 날짜를 기간으로 입력하고, ['A','B']의 column을 선택
df.loc['20160620':'20160623',['A','B']]
Out[55]:
A | B | |
---|---|---|
2016-06-20 | -0.554381 | 0.412571 |
2016-06-21 | 0.525805 | -0.358150 |
2016-06-22 | -0.739076 | -0.122611 |
2016-06-23 | 1.025927 | -0.772071 |
In [61]:
# 20160621의 이전의 row를 선택
df.loc[:'20160621']
Out[61]:
A | B | C | D | |
---|---|---|---|---|
2016-06-20 | -0.554381 | 0.412571 | 0.134686 | -0.307622 |
2016-06-21 | 0.525805 | -0.358150 | 1.292358 | 1.125330 |
In [60]:
df.loc['20160620',['A','B']]
Out[60]:
A -0.554381
B 0.412571
Name: 2016-06-20 00:00:00, dtype: float64
In [62]:
# dates[0]에 column'A'를 선택
df.loc[dates[0], 'A']
Out[62]:
-0.55438058642296195
In [63]:
df.at[dates[0],'A']
Out[63]:
-0.55438058642296195
selection by position
In [69]:
# N번째 row를 가져오는 방법 index의 location을 바로
df.iloc[3]
Out[69]:
A 1.025927
B -0.772071
C -0.455499
D -0.931907
Name: 2016-06-23 00:00:00, dtype: float64
In [75]:
# 3번째 ~ 5번째까지의 row를 가져오고 2부터 (4-1)의 column을 선택
df.iloc[3:5,2:4]
Out[75]:
C | D | |
---|---|---|
2016-06-23 | -0.455499 | -0.931907 |
2016-06-24 | -1.005543 | 0.983525 |
In [76]:
# 1,2,4row와 0,2의 column을 선택
df.iloc[[1,2,4],[0,2]]
Out[76]:
A | C | |
---|---|---|
2016-06-21 | 0.525805 | 1.292358 |
2016-06-22 | -0.739076 | -0.150623 |
2016-06-24 | 0.597701 | -1.005543 |
In [78]:
# row 1:3, column 전체
df.iloc[1:3,:]
Out[78]:
A | B | C | D | |
---|---|---|---|---|
2016-06-21 | 0.525805 | -0.358150 | 1.292358 | 1.125330 |
2016-06-22 | -0.739076 | -0.122611 | -0.150623 | -0.615627 |
In [79]:
# row 전체, column 1:3
df.iloc[:, 1:3]
Out[79]:
B | C | |
---|---|---|
2016-06-20 | 0.412571 | 0.134686 |
2016-06-21 | -0.358150 | 1.292358 |
2016-06-22 | -0.122611 | -0.150623 |
2016-06-23 | -0.772071 | -0.455499 |
2016-06-24 | 0.063475 | -1.005543 |
2016-06-25 | -1.262506 | 0.392729 |
In [80]:
df.iloc[1,1]
Out[80]:
-0.35814994083359336
In [81]:
df.iat[1,1]
Out[81]:
-0.35814994083359336
Boolean Indexing
In [83]:
df[df.A > 0]
Out[83]:
A | B | C | D | |
---|---|---|---|---|
2016-06-21 | 0.525805 | -0.358150 | 1.292358 | 1.125330 |
2016-06-23 | 1.025927 | -0.772071 | -0.455499 | -0.931907 |
2016-06-24 | 0.597701 | 0.063475 | -1.005543 | 0.983525 |
In [84]:
df[df > 0]
Out[84]:
A | B | C | D | |
---|---|---|---|---|
2016-06-20 | NaN | 0.412571 | 0.134686 | NaN |
2016-06-21 | 0.525805 | NaN | 1.292358 | 1.125330 |
2016-06-22 | NaN | NaN | NaN | NaN |
2016-06-23 | 1.025927 | NaN | NaN | NaN |
2016-06-24 | 0.597701 | 0.063475 | NaN | 0.983525 |
2016-06-25 | NaN | NaN | 0.392729 | 0.604364 |
In [85]:
df > 0
Out[85]:
A | B | C | D | |
---|---|---|---|---|
2016-06-20 | False | True | True | False |
2016-06-21 | True | False | True | True |
2016-06-22 | False | False | False | False |
2016-06-23 | True | False | False | False |
2016-06-24 | True | True | False | True |
2016-06-25 | False | False | True | True |
In [87]:
df2 = df.copy()
df2['E'] = ['one','one','two','three','four','three']
df2
Out[87]:
A | B | C | D | E | |
---|---|---|---|---|---|
2016-06-20 | -0.554381 | 0.412571 | 0.134686 | -0.307622 | one |
2016-06-21 | 0.525805 | -0.358150 | 1.292358 | 1.125330 | one |
2016-06-22 | -0.739076 | -0.122611 | -0.150623 | -0.615627 | two |
2016-06-23 | 1.025927 | -0.772071 | -0.455499 | -0.931907 | three |
2016-06-24 | 0.597701 | 0.063475 | -1.005543 | 0.983525 | four |
2016-06-25 | -0.210205 | -1.262506 | 0.392729 | 0.604364 | three |
In [93]:
df2['E'].isin(['two','four'])
Out[93]:
2016-06-20 False
2016-06-21 False
2016-06-22 True
2016-06-23 False
2016-06-24 True
2016-06-25 False
Freq: D, Name: E, dtype: bool
In [92]:
df2[df2['E'].isin(['two','four'])]
Out[92]:
A | B | C | D | E | |
---|---|---|---|---|---|
2016-06-22 | -0.739076 | -0.122611 | -0.150623 | -0.615627 | two |
2016-06-24 | 0.597701 | 0.063475 | -1.005543 | 0.983525 | four |
Setting
In [39]:
s1 = pd.Series([1,2,3,4,5,6], index=pd.date_range('20160620', periods=6))
s1
Out[39]:
2016-06-20 1
2016-06-21 2
2016-06-22 3
2016-06-23 4
2016-06-24 5
2016-06-25 6
Freq: D, dtype: int64
In [40]:
df['F'] = s1
In [41]:
df.at[dates[0], 'A'] = 0
In [42]:
df.iat[0,1] = 0
In [43]:
# numpy array를 set
df.loc[:,'D'] = np.array([5] * len(df))
In [44]:
df
Out[44]:
A | B | C | D | F | |
---|---|---|---|---|---|
2016-06-20 | 0.000000 | 0.000000 | 0.308792 | 5 | 1 |
2016-06-21 | 0.548566 | 2.039298 | -0.389184 | 5 | 2 |
2016-06-22 | -0.025059 | 0.410800 | 1.193115 | 5 | 3 |
2016-06-23 | -1.017573 | 0.257004 | 0.825450 | 5 | 4 |
2016-06-24 | 0.894756 | -0.973764 | 0.100148 | 5 | 5 |
2016-06-25 | 0.071252 | 0.696173 | 1.371591 | 5 | 6 |
In [47]:
# where operation
df2 = df.copy()
df2[df2 > 0] = -df2
df2
Out[47]:
A | B | C | D | F | |
---|---|---|---|---|---|
2016-06-20 | 0.000000 | 0.000000 | -0.308792 | -5 | -1 |
2016-06-21 | -0.548566 | -2.039298 | -0.389184 | -5 | -2 |
2016-06-22 | -0.025059 | -0.410800 | -1.193115 | -5 | -3 |
2016-06-23 | -1.017573 | -0.257004 | -0.825450 | -5 | -4 |
2016-06-24 | -0.894756 | -0.973764 | -0.100148 | -5 | -5 |
2016-06-25 | -0.071252 | -0.696173 | -1.371591 | -5 | -6 |
Missing Data
In [49]:
df1 = df.reindex(index=dates[0:4], columns=list(df.columns) + ['E'])
df1.loc[dates[0]:dates[1], 'E'] = 1
df1
Out[49]:
A | B | C | D | F | E | |
---|---|---|---|---|---|---|
2016-06-20 | 0.000000 | 0.000000 | 0.308792 | 5 | 1 | 1.0 |
2016-06-21 | 0.548566 | 2.039298 | -0.389184 | 5 | 2 | 1.0 |
2016-06-22 | -0.025059 | 0.410800 | 1.193115 | 5 | 3 | NaN |
2016-06-23 | -1.017573 | 0.257004 | 0.825450 | 5 | 4 | NaN |
In [51]:
df1.dropna(how='any')
Out[51]:
A | B | C | D | F | E | |
---|---|---|---|---|---|---|
2016-06-20 | 0.000000 | 0.000000 | 0.308792 | 5 | 1 | 1.0 |
2016-06-21 | 0.548566 | 2.039298 | -0.389184 | 5 | 2 | 1.0 |
In [53]:
df1.fillna(value=5)
Out[53]:
A | B | C | D | F | E | |
---|---|---|---|---|---|---|
2016-06-20 | 0.000000 | 0.000000 | 0.308792 | 5 | 1 | 1.0 |
2016-06-21 | 0.548566 | 2.039298 | -0.389184 | 5 | 2 | 1.0 |
2016-06-22 | -0.025059 | 0.410800 | 1.193115 | 5 | 3 | 5.0 |
2016-06-23 | -1.017573 | 0.257004 | 0.825450 | 5 | 4 | 5.0 |
In [54]:
df1.fillna(value=5)
Out[54]:
A | B | C | D | F | E | |
---|---|---|---|---|---|---|
2016-06-20 | 0.000000 | 0.000000 | 0.308792 | 5 | 1 | 1.0 |
2016-06-21 | 0.548566 | 2.039298 | -0.389184 | 5 | 2 | 1.0 |
2016-06-22 | -0.025059 | 0.410800 | 1.193115 | 5 | 3 | 5.0 |
2016-06-23 | -1.017573 | 0.257004 | 0.825450 | 5 | 4 | 5.0 |
Operations
In [66]:
df.mean(0)
Out[66]:
A 0.078657
B 0.404918
C 0.568319
D 5.000000
F 3.500000
dtype: float64
In [61]:
df.mean(1)
Out[61]:
2016-06-20 1.261758
2016-06-21 1.839736
2016-06-22 1.915771
2016-06-23 1.812976
2016-06-24 2.004228
2016-06-25 2.627803
Freq: D, dtype: float64
In [58]:
s = pd.Series([1,3,5,np.nan,6,8], index=dates).shift(2)
s
Out[58]:
2016-06-20 NaN
2016-06-21 NaN
2016-06-22 1.0
2016-06-23 3.0
2016-06-24 5.0
2016-06-25 NaN
Freq: D, dtype: float64
In [67]:
df.sub(s, axis='index')
Out[67]:
A | B | C | D | F | |
---|---|---|---|---|---|
2016-06-20 | NaN | NaN | NaN | NaN | NaN |
2016-06-21 | NaN | NaN | NaN | NaN | NaN |
2016-06-22 | -1.025059 | -0.589200 | 0.193115 | 4.0 | 2.0 |
2016-06-23 | -4.017573 | -2.742996 | -2.174550 | 2.0 | 1.0 |
2016-06-24 | -4.105244 | -5.973764 | -4.899852 | 0.0 | 0.0 |
2016-06-25 | NaN | NaN | NaN | NaN | NaN |
In [70]:
df.apply(np.cumsum)
Out[70]:
A | B | C | D | F | |
---|---|---|---|---|---|
2016-06-20 | 0.000000 | 0.000000 | 0.308792 | 5 | 1 |
2016-06-21 | 0.548566 | 2.039298 | -0.080393 | 10 | 3 |
2016-06-22 | 0.523507 | 2.450098 | 1.112722 | 15 | 6 |
2016-06-23 | -0.494066 | 2.707102 | 1.938172 | 20 | 10 |
2016-06-24 | 0.400690 | 1.733337 | 2.038320 | 25 | 15 |
2016-06-25 | 0.471941 | 2.429511 | 3.409912 | 30 | 21 |
In [72]:
df.apply(lambda x: x.max() - x.min())
Out[72]:
A 1.912329
B 3.013062
C 1.760776
D 0.000000
F 5.000000
dtype: float64
In [74]:
s = pd.Series(np.random.randint(0, 7, size=10))
s
Out[74]:
0 6
1 3
2 3
3 3
4 3
5 6
6 0
7 6
8 6
9 4
dtype: int64
In [76]:
s.value_counts()
Out[76]:
6 4
3 4
4 1
0 1
dtype: int64
In [78]:
s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat'])
s.str.lower()
Out[78]:
0 a
1 b
2 c
3 aaba
4 baca
5 NaN
6 caba
7 dog
8 cat
dtype: object
Merge
In [81]:
df = pd.DataFrame(np.random.randn(10, 4))
df
Out[81]:
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | -0.388622 | -0.005810 | -0.908106 | 0.484967 |
1 | -0.009531 | 0.822985 | -1.253726 | 0.124277 |
2 | 0.204007 | 1.143845 | 0.008254 | 0.232695 |
3 | -0.172336 | -0.696542 | 0.949102 | -0.482695 |
4 | -0.356362 | -0.210155 | 2.374065 | 0.685619 |
5 | 1.501421 | 0.641777 | 0.486696 | -0.615906 |
6 | 1.361051 | 0.942860 | -1.012667 | 0.284850 |
7 | 1.013987 | 1.627106 | -0.803233 | -0.017787 |
8 | 1.023373 | -0.908090 | 0.153074 | -0.028403 |
9 | 0.115687 | 1.477403 | 0.970383 | -0.726197 |
In [87]:
# Row를 나누는 작업임 0~2 의 rows, 3~6의 rows, 7~9의 rows
pieces = [df[:3], df[3:7], df[7:]]
# pieces[0] 0~2의 rows를 출력
#pieces
# 나뉘어진 pices를 붙이기 위해서 pd.concat()
pd.concat(pieces)
Out[87]:
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | -0.388622 | -0.005810 | -0.908106 | 0.484967 |
1 | -0.009531 | 0.822985 | -1.253726 | 0.124277 |
2 | 0.204007 | 1.143845 | 0.008254 | 0.232695 |
3 | -0.172336 | -0.696542 | 0.949102 | -0.482695 |
4 | -0.356362 | -0.210155 | 2.374065 | 0.685619 |
5 | 1.501421 | 0.641777 | 0.486696 | -0.615906 |
6 | 1.361051 | 0.942860 | -1.012667 | 0.284850 |
7 | 1.013987 | 1.627106 | -0.803233 | -0.017787 |
8 | 1.023373 | -0.908090 | 0.153074 | -0.028403 |
9 | 0.115687 | 1.477403 | 0.970383 | -0.726197 |
In [91]:
# Join
left = pd.DataFrame({'key': ['foo', 'foo'], 'lval': [1, 2]})
left
Out[91]:
key | lval | |
---|---|---|
0 | foo | 1 |
1 | foo | 2 |
In [93]:
right = pd.DataFrame({'key': ['foo', 'foo'], 'rval': [4, 5]})
right
Out[93]:
key | rval | |
---|---|---|
0 | foo | 4 |
1 | foo | 5 |
In [96]:
pd.merge(left, right, on='key')
Out[96]:
key | lval | rval | |
---|---|---|---|
0 | foo | 1 | 4 |
1 | foo | 1 | 5 |
2 | foo | 2 | 4 |
3 | foo | 2 | 5 |
In [98]:
df = pd.DataFrame(np.random.randn(8, 4), columns=['A','B','C','D'])
df
Out[98]:
A | B | C | D | |
---|---|---|---|---|
0 | -0.750785 | -0.982225 | -0.192320 | -1.018909 |
1 | -0.467425 | 1.396932 | -0.292926 | 0.866792 |
2 | 1.782684 | -0.309392 | -0.826318 | 1.455472 |
3 | 0.259205 | 0.160377 | -3.473742 | 0.928269 |
4 | -1.016813 | -1.737516 | 0.362811 | -0.861144 |
5 | 1.145282 | -0.242865 | 0.593853 | -0.099659 |
6 | -0.811005 | 0.753154 | 1.560544 | 0.409978 |
7 | -1.687995 | 1.007088 | 0.619152 | 0.191609 |
In [100]:
s = df.iloc[3]
df.append(s, ignore_index=True)
Out[100]:
A | B | C | D | |
---|---|---|---|---|
0 | -0.750785 | -0.982225 | -0.192320 | -1.018909 |
1 | -0.467425 | 1.396932 | -0.292926 | 0.866792 |
2 | 1.782684 | -0.309392 | -0.826318 | 1.455472 |
3 | 0.259205 | 0.160377 | -3.473742 | 0.928269 |
4 | -1.016813 | -1.737516 | 0.362811 | -0.861144 |
5 | 1.145282 | -0.242865 | 0.593853 | -0.099659 |
6 | -0.811005 | 0.753154 | 1.560544 | 0.409978 |
7 | -1.687995 | 1.007088 | 0.619152 | 0.191609 |
8 | 0.259205 | 0.160377 | -3.473742 | 0.928269 |
Grouping
In [104]:
df = pd.DataFrame({'A':['foo','bar','foo','bar','foo','bar','foo','foo'],
'B':['one','one','two','three','two','two','one','three'],
'C':np.random.randn(8),
'D':np.random.randn(8)})
df
Out[104]:
A | B | C | D | |
---|---|---|---|---|
0 | foo | one | -0.706122 | -0.329989 |
1 | bar | one | 1.657071 | -0.407027 |
2 | foo | two | -0.043819 | 1.957187 |
3 | bar | three | 0.470587 | -0.145247 |
4 | foo | two | -2.206332 | 0.652766 |
5 | bar | two | 0.672978 | -1.534902 |
6 | foo | one | -1.513980 | -1.805170 |
7 | foo | three | -0.026595 | -0.623450 |
In [106]:
# A Column을 group해서 합을 더한 값 C,D
df.groupby('A').sum()
Out[106]:
C | D | |
---|---|---|
A | ||
bar | 2.800637 | -2.087176 |
foo | -4.496849 | -0.148656 |
In [108]:
df.groupby(['A','B']).sum()
Out[108]:
C | D | ||
---|---|---|---|
A | B | ||
bar | one | 1.657071 | -0.407027 |
three | 0.470587 | -0.145247 | |
two | 0.672978 | -1.534902 | |
foo | one | -2.220103 | -2.135158 |
three | -0.026595 | -0.623450 | |
two | -2.250151 | 2.609953 |
Reshaping
In [136]:
# zip은 김밥을 생각하면 되는데 당근, 햄 넣고 두개를 동시에 자른다고 생각하면됩니다.
# 리스트를 두개 넣으면 각 리스트에서 한개씩 값을 가져와서 tuple로 생성합니다.
# zip(*[['a','b','c'],['d','e','f']])
# [('a', 'd'), ('b', 'e'), ('c', 'f')]
tuples = list(zip(*[['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]))
# print tuples
# [('bar', 'one'), ('bar', 'two'), ('baz', 'one'), ('baz', 'two'), ('foo', 'one'), ('foo', 'two'), ('qux', 'one'), ('qux', 'two')]
# ('bar', 'one')의 tupler값을 multiindex로 생성하는 방법
index = pd.MultiIndex.from_tuples(tuples, names=['first','second'])
print index
df = pd.DataFrame(np.random.randn(8,2), index=index, columns=['A', 'B'])
print df
df2 = df[:4]
print df2
MultiIndex(levels=[[u'bar', u'baz', u'foo', u'qux'], [u'one', u'two']],
labels=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]],
names=[u'first', u'second'])
A B
first second
bar one 0.953384 -0.269832
two 2.046435 0.074582
baz one -0.989456 0.792145
two -1.863672 0.381369
foo one 1.369745 0.635478
two -0.726009 -0.557414
qux one -1.680548 1.363867
two -0.554227 -0.011822
A B
first second
bar one 0.953384 -0.269832
two 2.046435 0.074582
baz one -0.989456 0.792145
two -1.863672 0.381369
In [139]:
stacked = df2.stack()
print stacked
print type(stacked)
print len(stacked)
print stacked[0]
first second
bar one A 0.953384
B -0.269832
two A 2.046435
B 0.074582
baz one A -0.989456
B 0.792145
two A -1.863672
B 0.381369
dtype: float64
<class 'pandas.core.series.Series'>
8
0.953383981031
In [126]:
stacked.unstack()
Out[126]:
A | B | ||
---|---|---|---|
first | second | ||
bar | one | -0.686062 | -0.933043 |
two | -1.853792 | 1.926521 | |
baz | one | -1.638858 | 0.366370 |
two | 0.287980 | -1.675488 |
In [128]:
stacked.unstack(1)
Out[128]:
second | one | two | |
---|---|---|---|
first | |||
bar | A | -0.686062 | -1.853792 |
B | -0.933043 | 1.926521 | |
baz | A | -1.638858 | 0.287980 |
B | 0.366370 | -1.675488 |
In [140]:
stacked.unstack(0)
Out[140]:
first | bar | baz | |
---|---|---|---|
second | |||
one | A | 0.953384 | -0.989456 |
B | -0.269832 | 0.792145 | |
two | A | 2.046435 | -1.863672 |
B | 0.074582 | 0.381369 |
Pivot Tables
In [142]:
df = pd.DataFrame({'A' : ['one', 'one', 'two', 'three'] * 3,
'B' : ['A', 'B', 'C'] * 4,
'C' : ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'] * 2,
'D' : np.random.randn(12),'E' : np.random.randn(12)})
print df
A B C D E
0 one A foo 0.266995 2.207506
1 one B foo -0.027444 0.257355
2 two C foo -1.775254 0.407818
3 three A bar -0.697476 -0.274161
4 one B bar 1.502007 0.278767
5 one C bar -2.535791 -0.203028
6 two A foo 0.772634 -2.020433
7 three B foo 1.313859 0.289895
8 one C foo 0.411518 -0.121833
9 one A bar 1.975446 -0.313777
10 two B bar 0.498896 -0.615964
11 three C bar 0.962692 -1.151602
In [162]:
# pivot table을 만들기 위해서 values로 사용할 값, index, columns을 넣어주면 된다.
# C를 만약에 column으로 사용한다면, C의 값들의 set이 column으로 사용이 된다.
# A, B를 index로 사용하면 row의 index로 사용이 된다.
pivot = pd.pivot_table(df, values=['D','E'], index=['A','B'], columns=['C'])
print pivot
# pivot에서 값을 접근하는 방법은 아래와 같음
print pivot['D']['bar']['one']['A']
D E
C bar foo bar foo
A B
one A 1.975446 0.266995 -0.313777 2.207506
B 1.502007 -0.027444 0.278767 0.257355
C -2.535791 0.411518 -0.203028 -0.121833
three A -0.697476 NaN -0.274161 NaN
B NaN 1.313859 NaN 0.289895
C 0.962692 NaN -1.151602 NaN
two A NaN 0.772634 NaN -2.020433
B 0.498896 NaN -0.615964 NaN
C NaN -1.775254 NaN 0.407818
1.97544617552
Time Series
In [181]:
# 2012년 1월 1일 0시 0분 0초 부터 시작해서 100개를 생성하는데, freq는 초를 단위로 해서 생성
rng = pd.date_range('1/1/2012', periods=100, freq='S')
ts = pd.Series(np.random.randint(0, 500, len(rng)), index=rng)
# 5분단위로 계산
ts.resample('5Min').sum()
Out[181]:
2012-01-01 26864
Freq: 5T, dtype: int64
In [186]:
# 하루를 기준으로 2012년 3월 6일부터 5개를
rng = pd.date_range('3/6/2012 00:00', periods=5, freq='D')
print rng
ts = pd.Series(np.random.randn(len(rng)), rng)
print ts
DatetimeIndex(['2012-03-06', '2012-03-07', '2012-03-08', '2012-03-09',
'2012-03-10'],
dtype='datetime64[ns]', freq='D')
2012-03-06 1.558119
2012-03-07 0.912712
2012-03-08 0.386135
2012-03-09 -1.332147
2012-03-10 -0.212428
Freq: D, dtype: float64
In [187]:
# time zone을 표시하거나 변경하는 방법
ts_utc = ts.tz_localize('UTC')
ts_utc.tz_convert('US/Eastern')
Out[187]:
2012-03-05 19:00:00-05:00 1.558119
2012-03-06 19:00:00-05:00 0.912712
2012-03-07 19:00:00-05:00 0.386135
2012-03-08 19:00:00-05:00 -1.332147
2012-03-09 19:00:00-05:00 -0.212428
Freq: D, dtype: float64
In [188]:
rng = pd.date_range('1/1/2012', periods=5, freq='M')
ts = pd.Series(np.random.randn(len(rng)), index=rng)
print ts
ps = ts.to_period()
print ps
ps.to_timestamp()
2012-01-31 0.948764
2012-02-29 -0.779314
2012-03-31 0.143111
2012-04-30 -0.152510
2012-05-31 0.304613
Freq: M, dtype: float64
2012-01 0.948764
2012-02 -0.779314
2012-03 0.143111
2012-04 -0.152510
2012-05 0.304613
Freq: M, dtype: float64
Out[188]:
2012-01-01 0.948764
2012-02-01 -0.779314
2012-03-01 0.143111
2012-04-01 -0.152510
2012-05-01 0.304613
Freq: MS, dtype: float64
In [192]:
# Quarterly frequency
prng = pd.period_range('1990Q1', '2000Q4', freq='Q-NOV')
print prng
ts = pd.Series(np.random.randn(len(prng)), prng)
ts.index = (prng.asfreq('M', 'e') + 1).asfreq('H', 's') + 9
ts.head()
PeriodIndex(['1990Q1', '1990Q2', '1990Q3', '1990Q4', '1991Q1', '1991Q2',
'1991Q3', '1991Q4', '1992Q1', '1992Q2', '1992Q3', '1992Q4',
'1993Q1', '1993Q2', '1993Q3', '1993Q4', '1994Q1', '1994Q2',
'1994Q3', '1994Q4', '1995Q1', '1995Q2', '1995Q3', '1995Q4',
'1996Q1', '1996Q2', '1996Q3', '1996Q4', '1997Q1', '1997Q2',
'1997Q3', '1997Q4', '1998Q1', '1998Q2', '1998Q3', '1998Q4',
'1999Q1', '1999Q2', '1999Q3', '1999Q4', '2000Q1', '2000Q2',
'2000Q3', '2000Q4'],
dtype='int64', freq='Q-NOV')
Out[192]:
1990-03-01 09:00 0.905044
1990-06-01 09:00 -0.215269
1990-09-01 09:00 1.373032
1990-12-01 09:00 0.833878
1991-03-01 09:00 0.675017
Freq: H, dtype: float64
Categoricals
In [213]:
# id, raw_grade를 columns으로 가지고 있는 테이블 생성
df = pd.DataFrame({"id":[1,2,3,4,5,6], "raw_grade":['a', 'b', 'b', 'a', 'a', 'e']})
df
Out[213]:
id | raw_grade | |
---|---|---|
0 | 1 | a |
1 | 2 | b |
2 | 3 | b |
3 | 4 | a |
4 | 5 | a |
5 | 6 | e |
In [217]:
df['grade'] = df['raw_grade'].astype('category')
print df['grade']
0 a
1 b
2 b
3 a
4 a
5 e
Name: grade, dtype: category
Categories (3, object): [a, b, e]
In [218]:
# grade의 값을 Series.cat.categories를 사용해서 의미이는 이름으로 변경하는 방법
df['grade'].cat.categories=['very good', 'good','very bad']
df
Out[218]:
id | raw_grade | grade | |
---|---|---|---|
0 | 1 | a | very good |
1 | 2 | b | good |
2 | 3 | b | good |
3 | 4 | a | very good |
4 | 5 | a | very good |
5 | 6 | e | very bad |
In [219]:
# 위에서 cat.categories는 length가 다르면 에러가 발생, 아래 set_categories는 categories를 추가.
# 만약 set_categories의 값이 기존에 없으면 NaN이 들어간다.
df["grade"] = df["grade"].cat.set_categories(["very bad", "bad", "medium", "good", "very good"])
print df['grade']
0 very good
1 good
2 good
3 very good
4 very good
5 very bad
Name: grade, dtype: category
Categories (5, object): [very bad, bad, medium, good, very good]
In [210]:
df.sort_values(by="grade")
Out[210]:
id | raw_grade | grade | |
---|---|---|---|
5 | 6 | e | very bad |
1 | 2 | b | good |
2 | 3 | b | good |
0 | 1 | a | very good |
3 | 4 | a | very good |
4 | 5 | a | very good |
In [212]:
# Category별로 몇개의 값이 있는지 확인
df.groupby("grade").size()
Out[212]:
grade
very bad 1
bad 0
medium 0
good 2
very good 3
dtype: int64
Plotting
In [232]:
%matplotlib inline
# pd.date_range를 이용해 2000년1월1일~ 1000개를 생성
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts = ts.cumsum()
try:
ts.plot()
except Exception:
pass
Data In/Out
In [258]:
# CSV 쓰는 방법
df.to_csv('foo.csv')
In [262]:
# CSV 읽는 방법
pd.read_csv('foo.csv').head()
Out[262]:
Unnamed: 0 | A | B | C | D | |
---|---|---|---|---|---|
0 | 2000-01-01 | 2.014510 | 0.789944 | -0.301766 | 1.175953 |
1 | 2000-01-02 | 1.278156 | -0.332712 | -1.962568 | 0.916521 |
2 | 2000-01-03 | 0.145005 | 2.245070 | 0.336035 | 0.396844 |
3 | 2000-01-04 | 1.155597 | 0.648062 | 0.371696 | 1.339735 |
4 | 2000-01-05 | -0.483881 | 0.277721 | -1.759100 | -0.605692 |
In [269]:
# excel 쓰는 방법
import openpyxl
df.to_excel('foo.xlsx', sheet_name='sheet1')
In [272]:
# excel 쓰는 방법
import xlrd
pd.read_excel('foo.xlsx', 'sheet1', index_col=None, na_values=['NA']).head()
Out[272]:
A | B | C | D | |
---|---|---|---|---|
2000-01-01 | 2.014510 | 0.789944 | -0.301766 | 1.175953 |
2000-01-02 | 1.278156 | -0.332712 | -1.962568 | 0.916521 |
2000-01-03 | 0.145005 | 2.245070 | 0.336035 | 0.396844 |
2000-01-04 | 1.155597 | 0.648062 | 0.371696 | 1.339735 |
2000-01-05 | -0.483881 | 0.277721 | -1.759100 | -0.605692 |
[참고] http://pandas.pydata.org/pandas-docs/stable/10min.html
'Big Data > 데이터 분석' 카테고리의 다른 글
[데이터 분석] Data Exploration Guide - The Art of Feature Engineering(4) (0) | 2021.05.03 |
---|---|
[데이터 분석] 머신러닝 예제 - Loan Prediction (0) | 2021.05.03 |
[데이터 분석] Data Exploration Guide - Outlier(3) (0) | 2021.05.03 |
[데이터 분석] Data Exploration Guide - Missing Value Treatment(2) (0) | 2021.05.03 |
[데이터 분석] Data Exploration Guide - (1) (0) | 2021.05.03 |