> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Jupyter 노트북 및 chDB로 데이터 탐색하기

> 이 가이드는 Jupyer 노트북에서 chDB를 설정하고 사용하여 ClickHouse Cloud 또는 로컬 파일의 데이터를 탐색하는 방법을 설명합니다

export const Image = ({img, alt, size = "lg"}) => {
  const normalizedSize = ["sm", "md", "lg"].includes(size) ? size : "lg";
  return <div className={`ch-image-${normalizedSize}`}>
      <Frame>
        <img src={img} alt={alt} />
      </Frame>
    </div>;
};

이 가이드에서는 ClickHouse 기반의 빠른 in-process SQL OLAP Engine인 [chDB](/docs/ko/chdb/index)를 사용해 Jupyter 노트북에서 ClickHouse Cloud의 데이터셋을 탐색하는 방법을 알아봅니다.

**사전 요구 사항**:

* 가상 환경
* 사용 가능한 ClickHouse Cloud 서비스와 [연결 정보](/docs/ko/products/cloud/guides/sql-console/connection-details)

<Tip>
  아직 ClickHouse Cloud 계정이 없다면 [가입](https://console.clickhouse.cloud/signUp?loc=docs-juypter-chdb)하여
  평가판을 시작하고 \$300의 무료 크레딧을 받을 수 있습니다.
</Tip>

**학습할 내용:**

* chDB를 사용하여 Jupyter 노트북에서 ClickHouse Cloud에 연결하기
* 원격 데이터셋을 쿼리하고 결과를 Pandas DataFrame으로 변환하기
* 분석을 위해 클라우드 데이터와 로컬 CSV 파일을 결합하기
* matplotlib를 사용해 데이터를 시각화하기

이 가이드에서는 ClickHouse Cloud에서 스타터 데이터셋 중 하나로 제공되는 UK Property Price 데이터셋을 사용합니다.
이 데이터셋에는 1995년부터 2024년까지 영국에서 거래된 주택 가격 데이터가 포함되어 있습니다.

<div id="setup">
  ## 설정
</div>

이 데이터셋을 기존 ClickHouse Cloud 서비스에 추가하려면 계정 정보로 [console.clickhouse.cloud](https://console.clickhouse.cloud/)에 로그인하십시오.

왼쪽 메뉴에서 `데이터 소스`를 클릭하십시오. 그런 다음 `Predefined sample data`를 클릭하십시오.

<Image size="md" img="https://mintcdn.com/private-7c7dfe99/0q34g_AjISMsyr4Q/images/use-cases/AI_ML/jupyter/1.webp?fit=max&auto=format&n=0q34g_AjISMsyr4Q&q=85&s=dd054bc5085a772e4337016df7ab421a" alt="예시 데이터셋 추가" width="4040" height="820" data-path="images/use-cases/AI_ML/jupyter/1.webp" />

영국 부동산 실거래가 데이터(4GB) 카드에서 `Get started`를 선택하십시오.

<Image size="md" img="https://mintcdn.com/private-7c7dfe99/0q34g_AjISMsyr4Q/images/use-cases/AI_ML/jupyter/2.webp?fit=max&auto=format&n=0q34g_AjISMsyr4Q&q=85&s=12bc6992c55a5e41e6999a1e603c59ae" alt="영국 실거래가 데이터셋 선택" width="3268" height="1164" data-path="images/use-cases/AI_ML/jupyter/2.webp" />

그런 다음 `Import dataset`를 클릭하십시오.

<Image size="md" img="https://mintcdn.com/private-7c7dfe99/0q34g_AjISMsyr4Q/images/use-cases/AI_ML/jupyter/3.webp?fit=max&auto=format&n=0q34g_AjISMsyr4Q&q=85&s=d27f44c54a8807f688aa9fae0718bfd4" alt="영국 실거래가 데이터셋 가져오기" width="3192" height="860" data-path="images/use-cases/AI_ML/jupyter/3.webp" />

ClickHouse는 `default` 데이터베이스에 `pp_complete` 테이블을 자동으로 생성하고, 가격 포인트 데이터 2,892만 행을 테이블에 채웁니다.

자격 증명이 노출될 가능성을 줄이기 위해 로컬 머신에서 Cloud 사용자 이름과 비밀번호를 환경 변수로 추가하는 것을 권장합니다.
터미널에서 다음 명령을 실행하여 사용자 이름과 비밀번호를 환경 변수로 추가하십시오:

```bash theme={null}
export CLICKHOUSE_USER=default
export CLICKHOUSE_PASSWORD=your_actual_password
```

<Note>
  위의 환경 변수는 현재 터미널 세션에서만 유지됩니다.
  영구적으로 설정하려면 셸 설정 파일에 추가하십시오.
</Note>

이제 가상 환경을 활성화하세요.
가상 환경에서 다음 명령으로 Jupyter Notebook을 설치하세요:

```python theme={null}
pip install notebook
```

다음 명령을 사용하여 Jupyter Notebook을 실행하세요:

```python theme={null}
jupyter notebook
```

새 브라우저 창이 열리며 `localhost:8888`에서 Jupyter 인터페이스가 표시됩니다.
새 노트북을 만들려면 `File` > `New` > `Notebook`을 클릭하세요.

<Image size="md" img="https://mintcdn.com/private-7c7dfe99/0q34g_AjISMsyr4Q/images/use-cases/AI_ML/jupyter/4.webp?fit=max&auto=format&n=0q34g_AjISMsyr4Q&q=85&s=dad3f58d9569424b1f3359438a5a4aee" alt="새 노트북 만들기" width="2296" height="2168" data-path="images/use-cases/AI_ML/jupyter/4.webp" />

커널을 선택하라는 메시지가 표시됩니다.
사용 가능한 Python 커널 중 아무 것이나 선택하면 되며, 이 예시에서는 `ipykernel`을 선택합니다:

<Image size="md" img="https://mintcdn.com/private-7c7dfe99/0q34g_AjISMsyr4Q/images/use-cases/AI_ML/jupyter/5.webp?fit=max&auto=format&n=0q34g_AjISMsyr4Q&q=85&s=cb715742ba5460bb9d4cfaf90c209350" alt="커널 선택" width="1892" height="872" data-path="images/use-cases/AI_ML/jupyter/5.webp" />

빈 셀에 다음 명령을 입력하면 원격 ClickHouse Cloud 인스턴스에 연결하는 데 사용할 chDB를 설치할 수 있습니다:

```python theme={null}
pip install chdb
```

이제 chDB를 import하고 간단한 쿼리를 실행해 설정이 올바른지 확인할 수 있습니다:

```python theme={null}
import chdb

result = chdb.query("SELECT 'Hello, ClickHouse!' as message")
print(result)
```

<div id="exploring-the-data">
  ## 데이터 살펴보기
</div>

이제 UK price paid 데이터가 준비되었고 Jupyter 노트북에서 chDB도 실행 중이므로, 데이터를 살펴볼 수 있습니다.

영국의 수도인 런던처럼 특정 지역에서 시간에 따라 가격이 어떻게 변했는지 확인한다고 가정해 보겠습니다.
ClickHouse의 [`remoteSecure`](/docs/ko/reference/functions/table-functions/remote) 함수를 사용하면 ClickHouse Cloud에서 데이터를 쉽게 가져올 수 있습니다.
chDB가 이 데이터를 프로세스 내에서 Pandas DataFrame으로 반환하도록 할 수 있으며, 이는 데이터를 다룰 때 편리하고 익숙한 방식입니다.

다음 쿼리를 작성하여 ClickHouse Cloud 서비스에서 UK price paid 데이터를 가져오고 `pandas.DataFrame`으로 변환하십시오:

```python theme={null}
import os
from dotenv import load_dotenv
import chdb
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

# Load environment variables from .env file
load_dotenv()

username = os.environ.get('CLICKHOUSE_USER')
password = os.environ.get('CLICKHOUSE_PASSWORD')

query = f"""
SELECT 
    toYear(date) AS year,
    avg(price) AS avg_price
FROM remoteSecure(
'****.europe-west4.gcp.clickhouse.cloud',
default.pp_complete,
'{username}',
'{password}'
)
WHERE town = 'LONDON'
GROUP BY toYear(date)
ORDER BY year;
"""

df = chdb.query(query, "DataFrame")
df.head()
```

위 스니펫에서 `chdb.query(query, "DataFrame")`는 지정된 쿼리를 실행하고 결과를 Pandas DataFrame으로 터미널에 출력합니다.
이 쿼리에서는 `remoteSecure` 함수를 사용해 ClickHouse Cloud에 연결합니다.
`remoteSecure` 함수는 다음을 매개변수로 받습니다:

* 연결 문자열
* 사용할 데이터베이스와 테이블 이름
* 사용자 이름
* 비밀번호

보안 모범 사례에 따라 사용자 이름 및 비밀번호 매개변수는 함수에 직접 지정하기보다 환경 변수를 사용하는 것이 좋습니다. 물론 원하면 직접 지정할 수도 있습니다.

`remoteSecure` 함수는 원격 ClickHouse Cloud 서비스에 연결해 쿼리를 실행하고 결과를 반환합니다.
데이터 크기에 따라 몇 초 정도 걸릴 수 있습니다.
이 예시에서는 연도별 평균 가격대를 반환하고, `town='LONDON'` 조건으로 필터링합니다.
그런 다음 결과는 `df`라는 변수에 DataFrame으로 저장됩니다.

`df.head`는 반환된 데이터의 처음 몇 개 행만 표시합니다:

<Image size="md" img="https://mintcdn.com/private-7c7dfe99/0q34g_AjISMsyr4Q/images/use-cases/AI_ML/jupyter/6.webp?fit=max&auto=format&n=0q34g_AjISMsyr4Q&q=85&s=0a803f2db20489b20e41bf1d036bef26" alt="데이터프레임 미리보기" width="1472" height="1040" data-path="images/use-cases/AI_ML/jupyter/6.webp" />

새 셀에서 다음 명령을 실행하여 컬럼의 타입을 확인하십시오:

```python theme={null}
df.dtypes
```

```response theme={null}
year          uint16
avg_price    float64
dtype: object
```

`date`는 ClickHouse에서는 `Date` 유형이지만, 결과 DataFrame에서는 `uint16` 유형이라는 점에 유의하십시오.
chDB는 DataFrame을 반환할 때 가장 적절한 유형을 자동으로 추론합니다.

이제 데이터를 익숙한 형태로 사용할 수 있으므로, 시간에 따라 런던의 부동산 가격이 어떻게 변했는지 살펴보겠습니다.

새 셀에서 다음 명령을 실행하여 matplotlib로 런던의 시점별 가격을 보여 주는 간단한 차트를 만드세요:

```python theme={null}
plt.figure(figsize=(12, 6))
plt.plot(df['year'], df['avg_price'], marker='o')
plt.xlabel('Year')
plt.ylabel('Price (£)')
plt.title('Price of London property over time')

# Show every 2nd year to avoid crowding
years_to_show = df['year'][::2]  # Every 2nd year
plt.xticks(years_to_show, rotation=45)

plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
```

<Image size="md" img="https://mintcdn.com/private-7c7dfe99/0q34g_AjISMsyr4Q/images/use-cases/AI_ML/jupyter/7.webp?fit=max&auto=format&n=0q34g_AjISMsyr4Q&q=85&s=a14f0d92f14f3a737da920e048193a51" alt="데이터프레임 미리보기" width="4040" height="1956" data-path="images/use-cases/AI_ML/jupyter/7.webp" />

예상하셨겠지만, 런던의 부동산 가격은 시간이 지나면서 크게 상승했습니다.

동료 데이터 과학자가 주택 관련 추가 변수가 담긴 .csv 파일을 보내왔고,
시간이 흐르면서 런던에서 판매된 주택 수가 어떻게 변했는지 궁금해하고 있습니다.
이제 이 변수들 중 일부를 주택 가격과 함께 시각화하여 상관관계가 있는지 살펴보겠습니다.

`file` 테이블 엔진을 사용하면 로컬 머신의 파일을 직접 읽을 수 있습니다.
새 셀에서 다음 명령을 실행하여 로컬 .csv 파일로 새 DataFrame을 만드십시오.

```python theme={null}
query = f"""
SELECT 
    toYear(date) AS year,
    sum(houses_sold)*1000
    FROM file('/Users/datasci/Desktop/housing_in_london_monthly_variables.csv')
WHERE area = 'city of london' AND houses_sold IS NOT NULL
GROUP BY toYear(date)
ORDER BY year;
"""

df_2 = chdb.query(query, "DataFrame")
df_2.head()
```

<Accordion title="한 단계에서 여러 소스 읽기">
  하나의 단계에서 여러 소스로부터 읽는 것도 가능합니다. 이를 위해 아래와 같이 `JOIN`을 사용하는 쿼리를 사용할 수 있습니다.

  ```python theme={null}
  query = f"""
  SELECT 
      toYear(date) AS year,
      avg(price) AS avg_price, housesSold
  FROM remoteSecure(
  '****.europe-west4.gcp.clickhouse.cloud',
  default.pp_complete,
  '{username}',
  '{password}'
  ) AS remote
  JOIN (
    SELECT 
      toYear(date) AS year,
      sum(houses_sold)*1000 AS housesSold
      FROM file('/Users/datasci/Desktop/housing_in_london_monthly_variables.csv')
    WHERE area = 'city of london' AND houses_sold IS NOT NULL
    GROUP BY toYear(date)
    ORDER BY year
  ) AS local ON local.year = remote.year
  WHERE town = 'LONDON'
  GROUP BY toYear(date)
  ORDER BY year;
  """
  ```
</Accordion>

<Image size="md" img="https://mintcdn.com/private-7c7dfe99/0q34g_AjISMsyr4Q/images/use-cases/AI_ML/jupyter/8.webp?fit=max&auto=format&n=0q34g_AjISMsyr4Q&q=85&s=a583ee2b2a3a60a7be81a2650ca67ee3" alt="데이터프레임 미리보기" width="1560" height="988" data-path="images/use-cases/AI_ML/jupyter/8.webp" />

2020년 이후 데이터는 없지만, 1995년부터 2019년까지는 두 데이터셋을 서로 비교해 시각화할 수 있습니다.
새 셀에서 다음 명령을 실행하세요.

```python theme={null}
# Create a figure with two y-axes
fig, ax1 = plt.subplots(figsize=(14, 8))

# Plot houses sold on the left y-axis
color = 'tab:blue'
ax1.set_xlabel('Year')
ax1.set_ylabel('Houses Sold', color=color)
ax1.plot(df_2['year'], df_2['houses_sold'], marker='o', color=color, label='Houses Sold', linewidth=2)
ax1.tick_params(axis='y', labelcolor=color)
ax1.grid(True, alpha=0.3)

# Create a second y-axis for price data
ax2 = ax1.twinx()
color = 'tab:red'
ax2.set_ylabel('Average Price (£)', color=color)

# Plot price data up until 2019
ax2.plot(df[df['year'] <= 2019]['year'], df[df['year'] <= 2019]['avg_price'], marker='s', color=color, label='Average Price', linewidth=2)
ax2.tick_params(axis='y', labelcolor=color)

# Format price axis with currency formatting
ax2.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, p: f'£{x:,.0f}'))

# Set title and show every 2nd year
plt.title('London Housing Market: Sales Volume vs Prices Over Time', fontsize=14, pad=20)

# Use years only up to 2019 for both datasets
all_years = sorted(list(set(df_2[df_2['year'] <= 2019]['year']).union(set(df[df['year'] <= 2019]['year']))))
years_to_show = all_years[::2]  # Every 2nd year
ax1.set_xticks(years_to_show)
ax1.set_xticklabels(years_to_show, rotation=45)

# Add legends
ax1.legend(loc='upper left')
ax2.legend(loc='upper right')

plt.tight_layout()
plt.show()
```

<Image size="md" img="https://mintcdn.com/private-7c7dfe99/0q34g_AjISMsyr4Q/images/use-cases/AI_ML/jupyter/9.webp?fit=max&auto=format&n=0q34g_AjISMsyr4Q&q=85&s=a39cbb698e0ac8e188b0b8756f496606" alt="원격 데이터셋과 로컬 데이터셋의 그래프" width="4040" height="2250" data-path="images/use-cases/AI_ML/jupyter/9.webp" />

그래프로 표시된 데이터를 보면, 판매량은 1995년에 약 160,000 수준에서 시작해 빠르게 증가했으며, 1999년에는 약 540,000으로 정점을 찍었습니다.
이후 거래량은 2000년대 중반까지 급격히 감소했고, 2007-2008년 금융 위기 동안 크게 떨어져 약 140,000 수준까지 하락했습니다.
반면 가격은 1995년 약 £150,000에서 2005년경 약 £300,000까지 꾸준히 상승했습니다.
2012년 이후에는 상승세가 크게 가속화되어, 약 £400,000에서 2019년에는 £1,000,000를 넘는 수준까지 가파르게 올랐습니다.
판매량과 달리 가격은 2008년 위기의 영향을 거의 받지 않았고, 상승 추세를 유지했습니다. 놀랍습니다!

<div id="summary">
  ## 요약
</div>

이 가이드에서는 chDB가 ClickHouse Cloud를 로컬 데이터 소스와 연결해 Jupyter 노트북에서 데이터를 원활하게 탐색할 수 있도록 지원하는 방법을 설명했습니다.
영국 부동산 가격 데이터셋을 사용해 `remoteSecure()` 함수로 원격 ClickHouse Cloud 데이터를 쿼리하고, `file()` 테이블 엔진으로 로컬 CSV 파일을 읽고, 결과를 분석 및 시각화를 위해 직접 Pandas DataFrame으로 변환하는 방법을 보여주었습니다.
chDB를 사용하면 데이터 과학자는 ClickHouse의 강력한 SQL 기능을 Pandas 및 matplotlib 같은 익숙한 Python 도구와 함께 활용할 수 있으므로, 여러 데이터 소스를 결합해 종합적인 분석을 손쉽게 수행할 수 있습니다.

런던에서 활동하는 많은 데이터 과학자에게 당장 내 집이나 아파트를 마련하는 일은 쉽지 않을 수 있지만, 적어도 자신을 시장 밖으로 밀어낸 그 시장을 분석할 수는 있습니다!
