> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-fix-nav-issues.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 如何使用 chDB 查询 Apache Arrow

> 本指南将介绍如何使用 chDB 查询 Apache Arrow 表

[Apache Arrow](https://arrow.apache.org/) 是一种标准化的列式内存格式，已在数据领域广受欢迎。
在本指南中，我们将学习如何使用 `Python` 表函数查询 Apache Arrow。

<div id="setup">
  ## 环境准备
</div>

先创建一个虚拟环境：

```bash theme={null}
python -m venv .venv
source .venv/bin/activate
```

现在我们来安装 chDB。
请确保版本为 2.0.2 或更高：

```bash theme={null}
pip install "chdb>=2.0.2"
```

接下来，我们来安装 PyArrow、pandas 和 ipython：

```bash theme={null}
pip install pyarrow pandas ipython
```

我们将使用 `ipython` 运行本指南后续部分中的命令，你可以通过运行以下命令来启动它：

```bash theme={null}
ipython
```

你也可以在 Python 脚本或常用的 notebook 中使用这段代码。

<div id="creating-an-apache-arrow-table-from-a-file">
  ## 从文件创建 Apache Arrow 表
</div>

首先，使用 [AWS CLI 工具](https://aws.amazon.com/cli/) 下载 [Ookla 数据集](https://github.com/teamookla/ookla-open-data) 中的一个 Parquet 文件：

```bash theme={null}
aws s3 cp \
  --no-sign \
  s3://ookla-open-data/parquet/performance/type=mobile/year=2023/quarter=2/2023-04-01_performance_mobile_tiles.parquet .
```

<Note>
  如果你想下载更多文件，可使用 `aws s3 ls` 列出所有文件，然后更新上述命令。
</Note>

接下来，我们将从 `pyarrow` 包中导入 Parquet 模块：

```python theme={null}
import pyarrow.parquet as pq
```

然后，我们可以将 Parquet 文件读取到 Apache Arrow 表中：

```python theme={null}
arrow_table = pq.read_table("./2023-04-01_performance_mobile_tiles.parquet")
```

schema 如下所示：

```python theme={null}
arrow_table.schema
```

```text theme={null}
quadkey: string
tile: string
tile_x: double
tile_y: double
avg_d_kbps: int64
avg_u_kbps: int64
avg_lat_ms: int64
avg_lat_down_ms: int32
avg_lat_up_ms: int32
tests: int64
devices: int64
```

我们可以通过 `shape` 属性获取行数和列数：

```python theme={null}
arrow_table.shape
```

```text theme={null}
(3864546, 11)
```

<div id="querying-apache-arrow">
  ## 查询 Apache Arrow
</div>

现在我们来通过 chDB 查询 Arrow 表。
首先，导入 chDB：

```python theme={null}
import chdb
```

接下来，我们可以描述这张表：

```python theme={null}
chdb.query("""
DESCRIBE Python(arrow_table)
SETTINGS describe_compact_output=1
""", "DataFrame")
```

```text theme={null}
               name     type
0           quadkey   String
1              tile   String
2            tile_x  Float64
3            tile_y  Float64
4        avg_d_kbps    Int64
5        avg_u_kbps    Int64
6        avg_lat_ms    Int64
7   avg_lat_down_ms    Int32
8     avg_lat_up_ms    Int32
9             tests    Int64
10          devices    Int64
```

我们也可以统计行数：

```python theme={null}
chdb.query("SELECT count() FROM Python(arrow_table)", "DataFrame")
```

```text theme={null}
   count()
0  3864546
```

现在，我们来做点更有意思的事。
以下查询会排除 `quadkey` 和 `tile.*` 列，然后计算其余所有列的平均值和最大值：

```python theme={null}
chdb.query("""
WITH numericColumns AS (
  SELECT * EXCEPT ('tile.*') EXCEPT(quadkey)
  FROM Python(arrow_table)
)
SELECT * APPLY(max), * APPLY(avg) APPLY(x -> round(x, 2))
FROM numericColumns
""", "Vertical")
```

```text theme={null}
Row 1:
──────
max(avg_d_kbps):                4155282
max(avg_u_kbps):                1036628
max(avg_lat_ms):                2911
max(avg_lat_down_ms):           2146959360
max(avg_lat_up_ms):             2146959360
max(tests):                     111266
max(devices):                   1226
round(avg(avg_d_kbps), 2):      84393.52
round(avg(avg_u_kbps), 2):      15540.4
round(avg(avg_lat_ms), 2):      41.25
round(avg(avg_lat_down_ms), 2): 554355225.76
round(avg(avg_lat_up_ms), 2):   552843178.3
round(avg(tests), 2):           6.31
round(avg(devices), 2):         2.88
```
