기본 콘텐츠로 건너뛰기

[matplotlib] 등고선(Contour)

데이터를 목록화하여 함수 적용_python

연속변수와 명목변수가 혼합된 데이터 셋의 경우 연속변수를 명목변수로 목록화하여 어떤 통계량을 계산할 필요가 있습니다. 특히 anova 등 분산분석시 이러한 과정이 필요합니다.

다음의 자료는 각 환기 시스템에 대한 유량을 측정한 것입니다. 
import numpy as np
import pandas as pd
>>> ven
    folate ventilation
1      243  N2O+O2,24h
2      251  N2O+O2,24h
3      275  N2O+O2,24h
...
20     270      O2,24h
21     293      O2,24h
22     328      O2,24h

위 자료들 중 ventilation의 종류에 따라 float를 분류할 목적입니다. ventilation의 종류는 pd.unique() 함수를 사용하여 알아볼수 있습니다. 이 함수는 데이터들 중 고유한 부분만을 추출하여 반환합니다. 
>>> idx=pd.unique(ven["ventilation"])
>>> idx
array(['N2O+O2,24h', 'N2O+O2,op', 'O2,24h'], dtype=object)

즉 ventilation은 3가지로 값들로 구성되어 있으며 이에 따라 float를 구분하여 각각에 대한 통계량을 계산하고자 합니다. 
우선 반복문을 사용하여 다음과 같이 분류하고 각 분류된 그룹화된 데이터셋에서 평균과 합을 계산할 수 있습니다. 
ven1={}
...: mu={}
...: tot={}
...: for i in idx:
...:     ven1[i]=ven[ven.iloc[:,1]==i].iloc[:,0]
...:     mu[i]=np.mean(ven1[i])
...:     tot[i]=np.sum(ven1[i])

ven1
Out[30]: 
{'N2O+O2,24h': 1    243
 2    251
 3    275
 4    291
 5    347
 6    354
 7    380
 8    392
 Name: folate, dtype: int64, 'N2O+O2,op': 9     206
 10    210
 11    226
 12    249
 13    255
 14    273
 15    285
 16    295
 17    309
 Name: folate, dtype: int64, 'O2,24h': 18    241
 19    258
 20    270
 21    293
 22    328
 Name: folate, dtype: int64}

mu
Out[31]: {'N2O+O2,24h': 316.625, 'N2O+O2,op': 256.44444444444446, 'O2,24h': 278.0}

tot
Out[32]: {'N2O+O2,24h': 2533, 'N2O+O2,op': 2308, 'O2,24h': 1390}

위와 같은 과정은 groupby()와 agg()함수로 간단하게 계산할 수 있습니다. 
DataFrame.groupby(['목록화할 변수이름'])
위 데이터에 시행하면 다음과 같습니다. 
x=ven.groupby(['ventilation'])

list(x)
Out[53]: 
[('N2O+O2,24h',    folate ventilation
  1     243  N2O+O2,24h
  2     251  N2O+O2,24h
  3     275  N2O+O2,24h
  4     291  N2O+O2,24h
  5     347  N2O+O2,24h
  6     354  N2O+O2,24h
  7     380  N2O+O2,24h
  8     392  N2O+O2,24h), ('N2O+O2,op',     folate ventilation
  9      206   N2O+O2,op
  10     210   N2O+O2,op
  11     226   N2O+O2,op
  12     249   N2O+O2,op
  13     255   N2O+O2,op
  14     273   N2O+O2,op
  15     285   N2O+O2,op
  16     295   N2O+O2,op
  17     309   N2O+O2,op), ('O2,24h',     folate ventilation
  18     241      O2,24h
  19     258      O2,24h
  20     270      O2,24h
  21     293      O2,24h
  22     328      O2,24h)]
위의 형태는 ventilation을 목록화 하였기 때문에 그에 따라 분류된 것을 볼 수 있습니다. 위 결과에 apply()함수를 적용하여 각 그룹의 평균과 합을 계산하여 보면 다음과 같습니다. 

mu=x.apply(np.mean, axis=0)

mu
Out[55]: 
                 folate
ventilation            
N2O+O2,24h   316.625000
N2O+O2,op    256.444444
O2,24h       278.000000

tot=x.apply(np.sum, axis=0)

tot
Out[57]: 
             folate                                        ventilation
ventilation                                                           
N2O+O2,24h     2533  N2O+O2,24hN2O+O2,24hN2O+O2,24hN2O+O2,24hN2O+O2...
N2O+O2,op      2308  N2O+O2,opN2O+O2,opN2O+O2,opN2O+O2,opN2O+O2,opN...
O2,24h         1390                     O2,24hO2,24hO2,24hO2,24hO2,24h

DataFrame.apply(함수, axis=0): apply()함수는 DataFrame 객체에 지정된 행 또는 열 (axis=1, 0)에 따라 인수로 전달한 함수를 적용합니다. axis의 기본값은 열(0)입니다.

apply() 함수와 유사하지만 여러개의 함수를 동시에 적용할 수 있다는 점이 다른 함수로 
DataFrame.agg(함수들, axis=0) 

ven.iloc[:,0].agg([np.sum, np.mean])
Out[63]: 
sum     6231.000000
mean     283.227273
Name: folate, dtype: float64

위와 같이 대상이 되는 DataFrame이 목록화된 것이라면 위의 객체 x에 apply()를 적용한 결과와 동일할 것입니다. 볼까요.
x.agg([np.sum, np.mean])
Out[64]: 
            folate            
               sum        mean
ventilation                   
N2O+O2,24h    2533  316.625000
N2O+O2,op     2308  256.444444
O2,24h        1390  278.000000

데이터의 목록화는 위에서 소개한 방법외에 피봇테이블을 작성하여 통계량을 계산할 수 있습니다. 사실 피봇테이블은 목록변수 2개에 대한 각각의 해당하는 값들을 나타내기 위한 것입니다. 
df = pd.DataFrame({'foo': ['one','one','one','two','two','two'],
...:                        'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
...:                        'baz': [1, 2, 3, 4, 5, 6]})
...: df.pivot(index='foo', columns='bar', values='baz')
Out[83]: 
bar  A  B  C
foo         
one  1  2  3
two  4  5  6
위 데이터는 foo, bar 두개의 목록변수에 따라 baz의 값을 나타낼 수 있습니다. 
Data.Frame.pivot(index, columns, value) : 결과에서 행이름(index), 열이름(columns), 표 내부의 값(values)

그러면 위의 결과 표에서 각 목록화된 변수 별로 통계량을 산출하기 위해서는 위에서 소개한 apply() 또는 agg() 함수를 사용할 수 있습니다. 위의 결과 객체의 type은 다음과 같이 DataFrame입니다. 
type(y)
Out[88]: pandas.core.frame.DataFrame
이 구조에서 apply(), agg() 함수를 사용하여 각 그룹에 대한 통계량을 계산할 수 있습니다.

 y.apply(np.mean, axis=1)
Out[18]:
foo
one    2.0
two    5.0
dtype: float64

y.apply(np.mean, axis=0)
Out[19]:
bar
A    2.5
B    3.5
C    4.5
dtype: float64

y.agg([np.mean, np.sum])
Out[20]:
        A    B    C
mean  2.5  3.5  4.5
sum   5.0  7.0  9.0
y.T.agg([np.mean, np.sum])
Out[21]:
      one   two
mean  2.0   5.0
sum   6.0  15.0

위의 과정을 한번에 적용할 수 있는 함수로 다음을 사용할 수 있습니다.
 pd.pivot_table(data, index=None, columns=None, aggfunc='mean',...)
위 함수는 지정한 index 또는 columns에 따라 분류된 값들에 함수(aggfunc)들을 적용합니다. 적용할 함수는 여러함수를 리스트 형식으로 지정할 수 있으며 기본은 np.mean 즉 평균을 계산입니다. 
pd.pivot_table(df, index='foo')
Out[84]: 
     baz
foo     
one    2
two    5
pd.pivot_table(df, index='bar')
Out[85]: 
     baz
bar     
A    2.5
B    3.5
C    4.5

pd.pivot_table(df, columns='bar')
Out[23]:
bar    A    B    C
baz  2.5  3.5  4.5

pd.pivot_table(df, index='bar', aggfunc=[np.mean, np.sum])
Out[26]:
    mean sum
     baz baz
bar       
A    2.5   5
B    3.5   7
C    4.5   9

댓글

이 블로그의 인기 게시물

[Linear Algebra] 유사변환(Similarity transformation)

유사변환(Similarity transformation) n×n 차원의 정방 행렬 A, B 그리고 가역 행렬 P 사이에 식 1의 관계가 성립하면 행렬 A와 B는 유사행렬(similarity matrix)이 되며 행렬 A를 가역행렬 P와 B로 분해하는 것을 유사 변환(similarity transformation) 이라고 합니다. (1)A=PBP1P1AP=B 식 2는 식 1의 양변에 B의 고유값을 고려한 것입니다. (식 2)BλI=P1APλP1P=P1(APλP)=P1(AλI)P 식 2의 행렬식은 식 3과 같이 정리됩니다. det(BλI)=det(P1(APλP))=det(P1)det((AλI))det(P)=det(P1)det(P)det((AλI))=det(AλI)det(P1)det(P)=det(P1P)=det(I) 유사행렬의 특성 유사행렬인 두 정방행렬 A와 B는 'A ~ B' 와 같...

[sympy] Sympy객체의 표현을 위한 함수들

Sympy객체의 표현을 위한 함수들 General simplify(x): 식 x(sympy 객체)를 간단히 정리 합니다. import numpy as np from sympy import * x=symbols("x") a=sin(x)**2+cos(x)**2 a sin2(x)+cos2(x) simplify(a) 1 simplify(b) x3+x2x1x2+2x+1 simplify(b) x - 1 c=gamma(x)/gamma(x-2) c Γ(x)Γ(x2) simplify(c) (x2)(x1) 위의 예들 중 객체 c의 감마함수(gamma(x))는 확률분포 등 여러 부분에서 사용되는 표현식으로 다음과 같이 정의 됩니다. 감마함수는 음이 아닌 정수를 제외한 모든 수에서 정의됩니다. 식 1과 같이 자연수에서 감마함수는 factorial(!), 부동소수(양의 실수)인 경우 적분을 적용하여 계산합니다. (식 1)Γ(n)={(n1)!n:자연수0xn1exdxn:부동소수 x=symbols('x') gamma(x).subs(x,4) 6 factorial 계산은 math.factorial() 함수를 사용할 수 있습니다. import math math.factorial(3) 6 a=gamma(x).subs(x,4.5) a.evalf(3) 11.6 simpilfy() 함수의 알고리즘은 식에서 공통사항을 찾아 정리하...

sympy.solvers로 방정식해 구하기

sympy.solvers로 방정식해 구하기 대수 방정식을 해를 계산하기 위해 다음 함수를 사용합니다. sympy.solvers.solve(f, *symbols, **flags) f=0, 즉 동차방정식에 대해 지정한 변수의 해를 계산 f : 식 또는 함수 symbols: 식의 해를 계산하기 위한 변수, 변수가 하나인 경우는 생략가능(자동으로 인식) flags: 계산 또는 결과의 방식을 지정하기 위한 인수들 dict=True: {x:3, y:1}같이 사전형식, 기본값 = False set=True :{(x,3),(y,1)}같이 집합형식, 기본값 = False ratioal=True : 실수를 유리수로 반환, 기본값 = False positive=True: 해들 중에 양수만을 반환, 기본값 = False 예 x2=1의 해를 결정합니다. solve() 함수에 적용하기 위해서는 다음과 같이 식의 한쪽이 0이 되는 형태인 동차식으로 구성되어야 합니다. x21=0 import numpy as np from sympy import * x = symbols('x') solve(x**2-1, x) [-1, 1] 위 식은 계산 과정은 다음과 같습니다. x21=0(x+1)(x1)=0x=1or1x4=1의 해를 결정합니다. solve() 함수의 인수 set=True를 지정하였으므로 결과는 집합(set)형으로 반환됩니다. eq=x**4-1 solve(eq, set=True) ([x], {(-1,), (-I,), (1,), (I,)}) 위의 경우 I는 복소수입니다.즉 위 결과의 과정은 다음과 같습니다. x41=(x2+1)(x+1)(x1)=0x=±1,±1=±i,±1 실수...