Ch19 Comparisons Decimal Calculations

Page content

I. 구글 클라우드 설정

본격적인 빅쿼리 실습에 앞서서, Python과 연동하는 예제를 준비하였다. 빅쿼리 시작에 앞서서 선행적으로 클라우드 사용을 해야 한다.

  1. 만약 GCP 프로젝트가 없다면, 계정을 연동한다. Go to Cloud Resource Manager
  2. 그리고, 비용결제를 위한 카드를 등록한다. Enable billing
  3. 마지막으로 BigQuery API를 사용해야 하기 때문에 빅쿼리 API 사용허가를 내준다.Enable BigQuery

위 API를 이용하지 않으면 Python 또는 R과 연동해서 사용할 수는 없다. 자주 쓰는것이 아니라면 비용은 거의 발생하지 않으니 염려하지 않아도 된다. 비용관리에 대한 자세한 내용은 BigQuery 권장사항: 비용 관리에서 확인하기를 바란다.

II. 사용자 계정 인증

구글 코랩을 사용해서 인증 절차를 밟도록 한다. 아래 소스코드는 변경시키지 않는다. 아래 절차대로 진행하면 된다. Gmail 인증 절차와 비슷하다.

from google.colab import auth
auth.authenticate_user()
print('Authenticated')
Authenticated

III. Comparisons

  • 비교는 연산자를 이용하여 실시한다.
  • 연산자 < , > , >=, 그리고 != (또는 )는 비교의 결과를 얻기 위해 사용된다.
  • 정렬을 한다면, NaN 뒤에 나오는 NULL은 유효 숫자(inf 포함)보다 작은 것으로 가정한다.
  • 그러나 NaN과의 비교는 항상 거짓을 반환하고 NULL과의 비교는 항상 NULL을 반환한다.
from google.cloud import bigquery
from tabulate import tabulate
import pandas as pd

project_id = 'your_project_id'
client = bigquery.Client(project=project_id)

temp = client.query('''
  WITH example AS (
      SELECT 
        'Sat' AS day
        , 1451 AS numrides
        , 1018 AS oneways
      UNION ALL SELECT 'SUN', 2376, 936
      UNION ALL SELECT 'Mon', NULL, NULL
      UNION ALL SELECT 'Tue', IEEE_DIVIDE(-3, 0), 
      0 -- this is -inf, 0
  )

  SELECT *
  from example
  ORDER BY numrides
  ''').to_dataframe()

print(temp)
   day  numrides  oneways
0  Mon       NaN      NaN
1  Tue      -inf      0.0
2  Sat    1451.0   1018.0
3  SUN    2376.0    936.0
  • 위 결과에서 순서상으로 NaN이 가장 낮은 순위로 정렬되고 있음을 보여주고 있다.

IV. Precise Decimal Calculations with NUMERIC

  • INT64와 FLOUT64는 유연하고 빠를 수 있도록 설계되었으나 계산에 사용할 때 컴퓨터 메모리의 64비트 영역에 베이스-2(0초와 1초) 형태로 저장된다는 점에 의해 제한된다.
  • 이것은 대부분의 애플리케이션에서 충분히 절충할 가치가 있지만, 재무 및 회계 애플리케이션은 종종 십진수(기본값 10)로 표시된 숫자에 대해 정확한 계산을 요구한다.
  • BigQuery의 숫자 데이터 유형은 숫자를 나타내는 38자리 숫자를 제공하며, 그 중 9자리 숫자가 소수점 뒤에 나타난다.
  • 저장용으로는 16바이트를 사용하며 십진수 분수를 정확히 나타낼 수 있어 재무 계산에 적합하다.
  • 예를 들어, 세 가지 지불의 합계를 계산해야 한다고 생각해 보십시오.
  • 당연히, 조회 결과가 정확하길 바랄 겁니다.
  • 그러나 FLOUT64 값을 사용할 경우 숫자가 메모리에 표시되는 방법과 숫자가 소수점 단위로 표시되는 방법 사이의 작은 차이가 다음과 같이 합산될 수 있다.
temp = client.query('''
  WITH example AS (
    SELECT 1.23 AS payment
    UNION ALL SELECT 7.89
    UNION ALL SELECT 12.43
  )
  
  SELECT 
    SUM(payment) AS total_paid, 
    AVG(payment) AS average_paid
  FROM example
  ''').to_dataframe()

print(temp)
   total_paid  average_paid
0       21.55      7.183333
  • 그런데, 금융 및 회계 애플리케이션에서 이러한 부정확한 표현은 장부에 작성할 때에는 조금 까다로워 질 수 있다. 지급 데이터 유형을 NUMBER로 변경하면 어떻게 되는지 보자.
temp = client.query('''
  WITH example AS (
    SELECT NUMERIC '1.23' AS payment
    UNION ALL SELECT NUMERIC '7.89'
    UNION ALL SELECT NUMERIC '12.43'
  )
  
  SELECT 
    SUM(payment) AS total_paid, 
    AVG(payment) AS average_paid
  FROM example
  ''').to_dataframe()

print(temp)
  total_paid average_paid
0      21.55  7.183333333
  • 지급액의 합계는 이제 보다 정밀해졌다.
  • 반복적인 소수점이기 때문에 평균은 숫자로도 정확하게 나타낼 수 없다.

V. Reference

Lakshmanan, V., & Tigani, J. (2020). Google BigQuery: the definitive guide: data warehousing, analytics, and machine learning at scale. Beijing: OReilly.