Python

Pandas 속도 비교 - loc vs replace

강의 홍보

개요

  • loc and Replace 속도를 비교 측정해본다..

방법 1. .loc vs .replace

  • 값을 바꾸는 방법은 다음과 같다.
    • data['column'].loc[data['column'] == 'Old Value'] = 'New Value'
import pandas as pd
import seaborn as sns
diamonds = sns.load_dataset('diamonds')
print(diamonds)
       carat        cut color clarity  depth  table  price     x     y     z
0       0.23      Ideal     E     SI2   61.5   55.0    326  3.95  3.98  2.43
1       0.21    Premium     E     SI1   59.8   61.0    326  3.89  3.84  2.31
2       0.23       Good     E     VS1   56.9   65.0    327  4.05  4.07  2.31
3       0.29    Premium     I     VS2   62.4   58.0    334  4.20  4.23  2.63
4       0.31       Good     J     SI2   63.3   58.0    335  4.34  4.35  2.75
...      ...        ...   ...     ...    ...    ...    ...   ...   ...   ...
53935   0.72      Ideal     D     SI1   60.8   57.0   2757  5.75  5.76  3.50
53936   0.72       Good     D     SI1   63.1   55.0   2757  5.69  5.75  3.61
53937   0.70  Very Good     D     SI1   62.8   60.0   2757  5.66  5.68  3.56
53938   0.86    Premium     H     SI2   61.0   58.0   2757  6.15  6.12  3.74
53939   0.75      Ideal     D     SI2   62.2   55.0   2757  5.83  5.87  3.64

[53940 rows x 10 columns]
  • cut Column에 있는 값 중, Premium을 Best로 바꿔보도록 한다.
import time
start_time = time.time()

diamonds['cut'].loc[diamonds['cut'] == 'Premium'] == 'Best'
print('Time using .loc[]: {} sec'.format(time.time() - start_time))
Time using .loc[]: 0.0020329952239990234 sec
  • 이번에는 replace 메서드를 사용해본다.
    • data['column'].replace('old value', 'new value', inplace = True
diamonds = sns.load_dataset('diamonds')

start_time = time.time()
diamonds.replace('Premium', 'Best', inplace=True)
print('Time using replace(): {} sec'.format(time.time() - start_time))
Time using replace(): 0.00027108192443847656 sec

Pandas 속도 비교 - iloc and loc

강의 홍보

1줄 요약

  • .loc[]와 .iloc[] 인덱스의 속도 차이를 측정해본다.

개요

  • 시간이 허락한다면, Pandas 속도를 비교하는 게시글을 자주 작성하려고 한다.
    • Pandas가 상대적으로 속도가 느리기 때문에, 조금 더 효율적인 코드를 작성하는 쪽에 초점을 맞춰본다.
  • .loc[] : index name locator를 의미한다.
  • iloc[] : index number locator를 의미한다.

행 선택시 속도 비교

  • 먼저 행을 선택할 때의 속도 차이를 확인하도록 합니다.
import pandas as pd
import time
import seaborn as sns

diamonds = sns.load_dataset("diamonds")
diamonds.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 53940 entries, 0 to 53939
Data columns (total 10 columns):
 #   Column   Non-Null Count  Dtype   
---  ------   --------------  -----   
 0   carat    53940 non-null  float64 
 1   cut      53940 non-null  category
 2   color    53940 non-null  category
 3   clarity  53940 non-null  category
 4   depth    53940 non-null  float64 
 5   table    53940 non-null  float64 
 6   price    53940 non-null  int64   
 7   x        53940 non-null  float64 
 8   y        53940 non-null  float64 
 9   z        53940 non-null  float64 
dtypes: category(3), float64(6), int64(1)
memory usage: 3.0 MB
  • 먼저 .loc 속도 측정을 해봅니다.
row_nums = range(0, 10000)

start_time = time.time()
rows = diamonds.loc[row_nums]
end_time = time.time()

print("Time using .loc[]: {} sec".format(end_time - start_time))
Time using .loc[]: 0.0029916763305664062 sec
  • 이번에는 동일하게 .iloc를 적용해봅니다.
start_time = time.time()
rows = diamonds.iloc[row_nums]
end_time = time.time()

print("Time using .iloc[]: {} sec".format(end_time - start_time))
Time using .iloc[]: 0.001990079879760742 sec

열 선택시 속도 비교

  • 이번에는 iloc를 활용하여 열을 선택합니다.
iloc_start_time = time.time()
cols = diamonds.iloc[:, [0, 2, 4, 6, 8]]
iloc_end_time = time.time()

print("Time using .iloc[]: {} sec".format(iloc_end_time - iloc_start_time))
Time using .iloc[]: 0.0009975433349609375 sec
  • 이번에는 Column명을 입력해서 추출하도록 합니다.
name_start_time = time.time()
cols = diamonds[['carat', 'color', 'depth', 'price', 'y']]
name_end_time = time.time()

print("Time using selection by name : {} sec".format(name_end_time - name_start_time))
Time using selection by name : 0.000997304916381836 sec

Reference

[Python] PyCaret Windows 10 아나콘다 설치 방법

강의 홍보

1줄 요약

  • 관리자 실행해서 아나콘다 가상 환경을 만든 후, 새로운 패키지를 설치한다.

PyCaret 설치 방법 (Windows 10)

  • 윈도우 10 환경에서 PyCaret 패키지를 설치해봅니다.
  • 아나콘다 설치에 관한 내용은 생략합니다. 다만, 이 때, 필요한 것은 환경변수에 추가가 되어 있어야 합니다.

가상환경 설정

  • 새로운 가상환경을 만듭니다. (이게 제일 편합니다.)
  • 명령프롬프트를 관리자로 실행합니다.

시간 측정의 중요성 및 방법

강의 홍보

1줄 요약

  • 코드를 효과적으로 작성해야 하는 이유를 확인한다.

Calculation 비교

  • 요한 카를 프리드리히 가우스(1777-1855)가 문제를 냈다고 알려짐

  • 1 + 2 + … + 1000000 까지 해당하는 모든 연속 양수의 합계를 구한다.

  • 두가지 방법이 존재한다.

[Python] PyDataset Library를 활용한 Sample 데이터 수집

강의 홍보

1줄 요약

  • R처럼 Sample 데이터를 쉽게 불러오자.

Sample Dataset

!pip install pydataset
Collecting pydataset
[?25l  Downloading https://files.pythonhosted.org/packages/4f/15/548792a1bb9caf6a3affd61c64d306b08c63c8a5a49e2c2d931b67ec2108/pydataset-0.2.0.tar.gz (15.9MB)
     |████████████████████████████████| 15.9MB 285kB/s 
[?25hRequirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (from pydataset) (1.1.5)
Requirement already satisfied: python-dateutil>=2.7.3 in /usr/local/lib/python3.7/dist-packages (from pandas->pydataset) (2.8.1)
Requirement already satisfied: numpy>=1.15.4 in /usr/local/lib/python3.7/dist-packages (from pandas->pydataset) (1.19.5)
Requirement already satisfied: pytz>=2017.2 in /usr/local/lib/python3.7/dist-packages (from pandas->pydataset) (2018.9)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/dist-packages (from python-dateutil>=2.7.3->pandas->pydataset) (1.15.0)
Building wheels for collected packages: pydataset
  Building wheel for pydataset (setup.py) ... [?25l[?25hdone
  Created wheel for pydataset: filename=pydataset-0.2.0-cp37-none-any.whl size=15939431 sha256=ebe470895a3467fe13c7654021e9108227a6dec8ce6da4f9b4e704520bcd6203
  Stored in directory: /root/.cache/pip/wheels/fe/3f/dc/5d02ccc767317191b12d042dd920fcf3432fab74bc7978598b
Successfully built pydataset
Installing collected packages: pydataset
Successfully installed pydataset-0.2.0
from pydataset import data
print(data())
        dataset_id                                             title
0    AirPassengers       Monthly Airline Passenger Numbers 1949-1960
1          BJsales                 Sales Data with Leading Indicator
2              BOD                         Biochemical Oxygen Demand
3     Formaldehyde                     Determination of Formaldehyde
4     HairEyeColor         Hair and Eye Color of Statistics Students
..             ...                                               ...
752        VerbAgg                  Verbal Aggression item responses
753           cake                 Breakage Angle of Chocolate Cakes
754           cbpp                 Contagious bovine pleuropneumonia
755    grouseticks  Data on red grouse ticks from Elston et al. 2001
756     sleepstudy       Reaction times in a sleep deprivation study
  • 데이터를 불러오는 코드를 작성한다.
cake = data("cake")
print(cake)

data("cake", show_doc=True)
     replicate recipe  temperature  angle  temp
1            1      A          175     42   175
2            1      A          185     46   185
3            1      A          195     47   195
4            1      A          205     39   205
5            1      A          215     53   215
..         ...    ...          ...    ...   ...
266         15      C          185     28   185
267         15      C          195     25   195
268         15      C          205     25   205
269         15      C          215     31   215
270         15      C          225     25   225
cake

PyDataset Documentation (adopted from R Documentation. The displayed examples are in R)

## Breakage Angle of Chocolate Cakes

### Description

Data on the breakage angle of chocolate cakes made with three different
recipes and baked at six different temperatures. This is a split-plot design
with the recipes being whole-units and the different temperatures being
applied to sub-units (within replicates). The experimental notes suggest that
the replicate numbering represents temporal ordering.

### Format

A data frame with 270 observations on the following 5 variables.

`replicate`

a factor with levels `1` to `15`

`recipe`

a factor with levels `A`, `B` and `C`

`temperature`

an ordered factor with levels `175` < `185` < `195` < `205` < `215` < `225`

`angle`

a numeric vector giving the angle at which the cake broke.

`temp`

numeric value of the baking temperature (degrees F).

### Details

The `replicate` factor is nested within the `recipe` factor, and `temperature`
is nested within `replicate`.

### Source

Original data were presented in Cook (1938), and reported in Cochran and Cox
(1957, p. 300). Also cited in Lee, Nelder and Pawitan (2006).

### References

Cook, F. E. (1938) _Chocolate cake, I. Optimum baking temperature_. Master's
Thesis, Iowa State College.

Cochran, W. G., and Cox, G. M. (1957) _Experimental designs_, 2nd Ed. New
York, John Wiley \& Sons.

Lee, Y., Nelder, J. A., and Pawitan, Y. (2006) _Generalized linear models with
random effects. Unified analysis via H-likelihood_. Boca Raton, Chapman and
Hall/CRC.

### Examples

    str(cake)
    ## 'temp' is continuous, 'temperature' an ordered factor with 6 levels
    (fm1 <- lmer(angle ~ recipe * temperature + (1|recipe:replicate), cake, REML= FALSE))
    (fm2 <- lmer(angle ~ recipe + temperature + (1|recipe:replicate), cake, REML= FALSE))
    (fm3 <- lmer(angle ~ recipe + temp        + (1|recipe:replicate), cake, REML= FALSE))
    ## and now "choose" :
    anova(fm3, fm2, fm1)

(Python) Pandas Data Convert

강의 홍보

1줄 요약

  • Pandas에서 데이터 형변환은 astype로 끝낸다.

참고자료

예제

  • 가상의 temp 데이터를 만든다.
  • 모두 0, 1, 2 데이터이지만 각 데이터 타입은 모두 다르다.
import pandas as pd

temp = pd.DataFrame({"A": [0,1,2], 
                     "B": ["0", "1", "2"], 
                     "C": [0.0, 1.0, 2.0]})

temp.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 3 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   A       3 non-null      int64  
 1   B       3 non-null      object 
 2   C       3 non-null      float64
dtypes: float64(1), int64(1), object(1)
memory usage: 200.0+ bytes
print(temp)
   A  B  C
0  0  0  0
1  1  1  1
2  2  2  2

확인

  • 변환을 진행할 때는, 아래와 같이 확인하는 용도로 우선 확인한다. 이 때 확인해야 하는 것은 dtype: ~ 이다.
  • 보시다시피 정상적으로 잘 변환되는 것을 알 수 있다.
temp["A"].astype(str)
0    0
1    1
2    2
Name: A, dtype: object
temp["B"].astype(int)
0    0
1    1
2    2
Name: B, dtype: int64
temp["C"].astype(int)
0    0
1    1
2    2
Name: C, dtype: int64

적용

  • 이제 본 데이터에 적용을 해본다.
temp["A"] = temp["A"].astype(str)
temp["B"] = temp["B"].astype(int)
temp["C"] = temp["C"].astype(int)

temp.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 3 columns):
 #   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
 0   A       3 non-null      object
 1   B       3 non-null      int64 
 2   C       3 non-null      int64 
dtypes: int64(2), object(1)
memory usage: 200.0+ bytes
  • 처음과 달라진 Dtype를 확인할 수 있을 것이다.
  • 간단한 문법이지만, 막상 실무에서 적용하려면 생각이 잘 나지 않을수도 있다. 작은 도움이 되기를 바란다.

Happy To Code

(Python) Defining the Encoding

1줄 요약

  • 공식 문서를 한번 읽어보도록 합니다.

Why?

  • 한글 사용자에게 인코딩은 언제나 어렵습니다. 한글 깨져요…
  • 그리고 파이썬의 기본 인코딩은 ASCII라 합니다.

How to use

  • 임의의 .py 파일에서 다음과 같이 시작을 합니다.
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os, sys
...

References

파이썬 객체 지향 프로그래밍 - Attributes & Methods (2)

1줄 요약

  • 클래스를 직접 구현하면서 Attributes & Methods의 차이점에 대해 이해한다.

개요

  • 기본적인 클래스 등을 작성해본다.
class Customer:
    pass
  • class <name>: 클래스의 이름을 정의함
  • 만약, pass를 입력하면 하나의 empty 클래스를 생성하는 것이다.
  • 이렇게 생성된 클래스는 여러개의 인스턴스를 만들 수 있음
c1 = Customer() 
c2 = Customer()

Methods 추가

  • 이번에는 간단한 method를 추가한다.
class Customer:
    def identify(self, name): 
        print("저는 소비자 " + name + " 입니다.")
  • 함수 작성 시에는 self를 가장 먼저 입력한다.
cust = Customer()
cust.identify("Evan")
저는 소비자 Evan 입니다.
  • Self를 어떻게 이해하면 좋을까? 다양한 프로그래밍 설명이 있지만, 직관적으로 표현하면, instance 자기 자신이라고 표현하는 것이 맞다.
    • cust.identify(“Evan”)는 Customer.identify(cust, “Evan”)이라고 해석하는 것과 동일하다.

Attributes 추가

  • 이번에는 Attributes를 추가한다.
class Customer:
    
    def set_name(self, new_name):
        self.name = new_name
  • set_name이 호출 될 때, .name도 같이 호출 된다.
  • 조금더 구체적으로 살펴보면 다음과 같다.
cust2 = Customer() # 이 때에는 .name이 존재하지 않는다. 
cust2.set_name("Evan") # 이 때에는 .name이 생성되며, "Evan" 이름이 저장된다. 
print(cust2.name) # 정상적으로 호출이 된다
Evan
  • 이번에는 identify 메서드 형식을 바꾸도록 한다.
class Customer:
    
    def set_name(self, new_name):
        self.name = new_name
        
    def identify(self): 
        print("저는 소비자 " + self.name + " 입니다.")
  • idenfity( ) 내부에 name 인자는 없었졌다. 그리고, print( ) 내부에 있는 name은 self.name으로 변경 된다.
cust = Customer()
cust.set_name("Evan")
cust.identify()
저는 소비자 Evan 입니다.

References

파이썬 객체 지향 프로그래밍 - Attributes & Methods

1줄 요약

  • Attributes & Methods의 차이점에 대해 이해한다.

개요

  • Object = State + Behavior
    • 예) Email, Phone Number, 배송상태
  • Class는 일종의 가이드라인을 의미
  • 파이썬 내의 모든 객체는 일종으 클래스임
ObjectClass
7int
“Hello”str
pd.DataFrame()DataFrame
  • 해당 클래스를 찾기 위해 type( )를 사용함.
import numpy as np
temp = np.array([1, 2, 3])
print(type(temp))
<class 'numpy.ndarray'>

State + Behavior

  • 그렇다면, State를 지칭하는 파이썬 문법은 무엇인가?
    • 파이썬에서는 이를 Attributes라고 부른다.
  • 또한, Behavior를 지칭하는 파이썬 문법은 무엇인가?
    • 파이썬에서는 이를 Methods라고 부른다.
  • 먼저 Attributes 문법을 확인해본다.
# shape attribute
temp.shape
(3,)
  • 이번에는 Methods 문법을 확인해본다.
# reshpae method
temp.reshape(3, 1)
array([[1],
       [2],
       [3]])

소결

  • Object = Attributes + Methods
    • attribute <-> variables <-> obj.my_attribute,
    • attribute <-> function() <-> obj.my_method().
  • dir() 해당 객체의 모든 attributes, methods를 보여줌
dir(temp)
['T',
 '__abs__',
 '__add__',
 '__and__',
 '__array__',
 '__array_finalize__',
 '__array_function__',
 '__array_interface__',
 '__array_prepare__',
 '__array_priority__',
 '__array_struct__',
 '__array_ufunc__',
 '__array_wrap__',
 '__bool__',
 '__class__',
 '__complex__',
 '__contains__',
 '__copy__',
 '__deepcopy__',
 '__delattr__',
 '__delitem__',
 '__dir__',
 '__divmod__',
 '__doc__',
 '__eq__',
 '__float__',
 '__floordiv__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__getitem__',
 '__gt__',
 '__hash__',
 '__iadd__',
 '__iand__',
 '__ifloordiv__',
 '__ilshift__',
 '__imatmul__',
 '__imod__',
 '__imul__',
 '__index__',
 '__init__',
 '__init_subclass__',
 '__int__',
 '__invert__',
 '__ior__',
 '__ipow__',
 '__irshift__',
 '__isub__',
 '__iter__',
 '__itruediv__',
 '__ixor__',
 '__le__',
 '__len__',
 '__lshift__',
 '__lt__',
 '__matmul__',
 '__mod__',
 '__mul__',
 '__ne__',
 '__neg__',
 '__new__',
 '__or__',
 '__pos__',
 '__pow__',
 '__radd__',
 '__rand__',
 '__rdivmod__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__rfloordiv__',
 '__rlshift__',
 '__rmatmul__',
 '__rmod__',
 '__rmul__',
 '__ror__',
 '__rpow__',
 '__rrshift__',
 '__rshift__',
 '__rsub__',
 '__rtruediv__',
 '__rxor__',
 '__setattr__',
 '__setitem__',
 '__setstate__',
 '__sizeof__',
 '__str__',
 '__sub__',
 '__subclasshook__',
 '__truediv__',
 '__xor__',
 'all',
 'any',
 'argmax',
 'argmin',
 'argpartition',
 'argsort',
 'astype',
 'base',
 'byteswap',
 'choose',
 'clip',
 'compress',
 'conj',
 'conjugate',
 'copy',
 'ctypes',
 'cumprod',
 'cumsum',
 'data',
 'diagonal',
 'dot',
 'dtype',
 'dump',
 'dumps',
 'fill',
 'flags',
 'flat',
 'flatten',
 'getfield',
 'imag',
 'item',
 'itemset',
 'itemsize',
 'max',
 'mean',
 'min',
 'nbytes',
 'ndim',
 'newbyteorder',
 'nonzero',
 'partition',
 'prod',
 'ptp',
 'put',
 'ravel',
 'real',
 'repeat',
 'reshape',
 'resize',
 'round',
 'searchsorted',
 'setfield',
 'setflags',
 'shape',
 'size',
 'sort',
 'squeeze',
 'std',
 'strides',
 'sum',
 'swapaxes',
 'take',
 'tobytes',
 'tofile',
 'tolist',
 'tostring',
 'trace',
 'transpose',
 'var',
 'view']

References

[Python] Open API를 활용한 Air Quality 데이터 수집 예제

강의 홍보

1줄 요약

  • 오픈 데이터로 활용하여 시계열 데이터를 확보해보자.

동기 부여

  • Pandas 공식 홈페이지가 살짝 바뀐 듯 하였다.
  • 시계열 데이터를 다루는 페이지를 확인하던 중 open air quality data API가 있는 것을 확인하였다.

라이브러리 설치

  • 라이브러리 설치는 비교적 간단하다.
$ pip install py-openaq
Collecting py-openaq
  Downloading py-openaq-1.1.0.tar.gz (7.9 kB)
Building wheels for collected packages: py-openaq
  Building wheel for py-openaq (setup.py) ... done
  Created wheel for py-openaq: filename=py_openaq-1.1.0-py3-none-any.whl size=9036 sha256=1d5011bd3ef180c93d275081f6f5ad20d569c9f7ce2982eabaaeee7307070b75
  Stored in directory: /Users/evan/Library/Caches/pip/wheels/01/1d/be/6b6a0ee792bbc9138aeb645707cdad8da741bb2d789beb04d9
Successfully built py-openaq
Installing collected packages: py-openaq
Successfully installed py-openaq-1.1.0

데이터 불러오기

  • 데이터를 불러오면 다음과 같다.
import openaq
api = openaq.OpenAQ()

location = "FR04014"
date_from = "2019-05-07T01:00:00" 
date_to = "2019-06-21T00:00:00" 
parameter = "no2"

FR04014_results = api.measurements(location=location, 
                                   parameter=parameter, 
                                   date_from=date_from, 
                                   date_to=date_to, 
                                   limit=10000,
                                   df=True, 
                                   index='local')
print(FR04014_results.shape)
FR04014_results.head()
(1002, 9)
locationparametervalueunitcountrycitydate.utccoordinates.latitudecoordinates.longitude
date.local
2019-06-21 02:00:00FR04014no220.0b'\xc2\xb5g/m\xc2\xb3'FRParis2019-06-21 00:00:00+00:0048.8372432.393902
2019-06-21 01:00:00FR04014no221.8b'\xc2\xb5g/m\xc2\xb3'FRParis2019-06-20 23:00:00+00:0048.8372432.393902
2019-06-21 00:00:00FR04014no226.5b'\xc2\xb5g/m\xc2\xb3'FRParis2019-06-20 22:00:00+00:0048.8372432.393902
2019-06-20 23:00:00FR04014no224.9b'\xc2\xb5g/m\xc2\xb3'FRParis2019-06-20 21:00:00+00:0048.8372432.393902
2019-06-20 22:00:00FR04014no221.4b'\xc2\xb5g/m\xc2\xb3'FRParis2019-06-20 20:00:00+00:0048.8372432.393902
  • 정상적으로 데이터가 불러오진 것을 확인할 수 있다.
  • 다음은 3개의 데이터셋을 만들어서 합친 후, 시계열 데이터 핸들링을 연습해보독 한다.

Reference

HP-Nunes.(2020). An Introduction to Data Collection: REST APIs with Python & Pizzas, Medium, Retrieved from https://medium.com/@geocuriosity/an-introduction-to-data-collection-rest-apis-with-python-pizzas-7b682cef676c