从 Web 数据源和 API 获取数据
Kotlin Notebook 提供了强大的平台, 能够从各种 Web 数据源和 API 访问和操作数据. 它提供了一个交互环境, 在这个环境中每个步骤都能够可视化, 清晰可见, 因此简化了数据抽取和分析任务. 这样的功能使得它非常适合于探索那些你不熟悉的 API.
Kotlin Notebook 在与 Kotlin DataFrame 库 结合使用时, 不仅能让你连接到 API, 从 API 获取 JSON 数据, 还能帮助你重塑这些数据, 用于全面的分析和可视化.
开始前的准备工作
下载并安装最新版的 IntelliJ IDEA Ultimate.
在 IntelliJ IDEA 中安装 Kotlin Notebook plugin.
选择 File | New | Kotlin Notebook, 创建一个新的 Kotlin Notebook.
在 Kotlin Notebook 中, 运行以下命令, 导入 Kotlin DataFrame 库:
%use dataframe
从 API 获取数据
使用 Kotlin Notebook 和 Kotlin DataFrame 库从 API 获取数据, 是通过 .read()
函数完成的, 类似于 从文件获取数据, 例如 CSV 或 JSON. 但是, 在使用基于 Web 的数据源时, 你可能需要额外的格式化处理, 来将原始的 API 数据转换为结构化的格式.
我们来看一个从 YouTube 数据 API 获取数据的示例:
打开你的 Kotlin Notebook 文件 (
.ipynb
).导入 Kotlin DataFrame 库, 数据处理任务需要使用它. 在一个代码单元(Code Cell)中运行以下命令:
%use dataframe在一个新的代码单元中安全的添加你的 API Key, 这个 Key 用来对 YouTube 数据 API 请求进行认证. 你可以从 credentials 页面 得到你的 API Key:
val apiKey = "YOUR-API_KEY"创建一个 load 函数, 参数是一个表示 path 的字符串, 并使用 DataFrame 的
.read()
函数, 从 YouTube 数据 API 获取数据:fun load(path: String): AnyRow = DataRow.read("https://www.googleapis.com/youtube/v3/$path&key=$apiKey")将获取的数据组织为行, 并通过
nextPageToken
处理 YouTube API 的分页. 这可以保证你能够得到跨越多页的数据:fun load(path: String, maxPages: Int): AnyFrame { // 初始化一个可变的 List, 保存数据的行. val rows = mutableListOf<AnyRow>() // 设置初始页的 path, 用于载入数据. var pagePath = path do { // 从当前页的 path 载入数据. val row = load(pagePath) // 将载入的数据作为行, 添加到 List. rows.add(row) // 如果存在, 获得下一页的 token. val next = row.getValueOrNull<String>("nextPageToken") // 更新页的 path, 用于取得下一页, 其中包含新的 token. pagePath = path + "&pageToken=" + next // 继续装载, 直到不存在下一页. } while (next != null && rows.size < maxPages) // 拼接已装载的所有行, 并作为 DataFrame 返回. return rows.concat() }在一个新的代码单元中, 使用前面定义的
load()
函数, 获取数据并创建一个 DataFrame. 这个示例会获取数据, 这里是关于 Kotlin 的视频, 每页最大 50 条结果, 最大 5 页. 结果保存在df
变量中:val df = load("search?q=kotlin&maxResults=50&part=snippet", 5) df最后, 从 DataFrame 抽取元素, 并拼接在一起:
val items = df.items.concat() items
清理和优化(Refine)数据
准备你的数据集用于分析时, 清理和优化(Refine)数据是关键步骤. Kotlin DataFrame 库 为这些任务提供了强大的功能. move
, concat
, select
, parse
, 和 join
等方法, 对于组织和转换你的数据至关重要.
我们来看一个示例, 其中的数据已经 使用 YouTube 的数据 API 获取 了. 目标是清理并重构数据集, 以便进行深入分析:
你可以首先重整并清理你的数据. 包括将某些列移动到新标题下, 以及删除不需要的列, 以提高清晰度:
val videos = items.dropNulls { id.videoId } .select { id.videoId named "id" and snippet } .distinct() videos从清理后的数据获取分块 ID (Chunk ID), 并装载对应的视频统计数据. 包括将数据分为较小的批次, 并获取更多详细信息:
val statPages = clean.id.chunked(50).map { val ids = it.joinToString("%2C") load("videos?part=statistics&id=$ids") } statPages将获取的统计数据拼接起来, 并选择相关的列:
val stats = statPages.items.concat().select { id and statistics.all() }.parse() stats将已有的清理后的数据, 与新获取统计数据结合起来. 这一步会将 2 组数据合并为一个综合的 DataFrame:
val joined = clean.join(stats) joined
这个示例演示了如何使用 Kotlin DataFrame 的各种函数清理, 重组织, 并增强你的数据集. 每个步骤都是为了优化数据, 使得它更适合于 深入分析.
在 Kotlin Notebook 中分析数据
在你成功的使用 Kotlin DataFrame 库 的函数 获取 并 清理和优化你的数据 之后, 下一步是分析这个准备好的数据集, 抽取有意义的信息.
有很多有用的方法, 例如 groupBy
用于数据分组, sum
和 maxBy
用于 汇总统计, 以及 sortBy
用于数据排序. 通过这些工具, 你可以高效的执行复杂的数据分析任务.
我们来看一个示例, 使用 groupBy
对视频按照 channel 进行分组, 使用 sum
计算每个分组的总计观看次数, 使用 maxBy
查找每个组中最新的或最多观看次数的视频:
设置引用, 简化对特定列的访问:
val view by column<Int>()使用
groupBy
方法, 根据channel
列分组数据, 并排序.val channels = joined.groupBy { channel }.sortByCount()在结果表中, 你可以交互式的浏览数据. 每行对应一个 channel, 点击一行的
group
字段, 会展开这个行, 显示这个 channel 的视频的更多细节.你可以点击左下方的表格图标, 返回分组的数据集.
使用
aggregate
,sum
,maxBy
, 和flatten
, 创建一个 DataFrame, 汇总每个 channel 的总计观看次数, 以及它的最新或最多观看次数的视频的详细信息:val aggregated = channels.aggregate { viewCount.sum() into view val last = maxBy { publishedAt } last.title into "last title" last.publishedAt into "time" last.viewCount into "viewCount" // 对 DataFrame 根据观看次数逆序排序, 并转换为扁平结构. }.sortByDesc(view).flatten() aggregated
分析结果如下:
关于更多高级技术, 请参见 Kotlin DataFrame 文档.
下一步做什么
学习使用 Kandy 库 进行数据可视化.
阅读 在 Kotlin Notebook 中使用 Kandy 进行数据可视化, 学习数据可视化的更多知识.
关于 Kotlin 中用于数据科学和分析的工具和资源的广泛的概述, 请参见 用于数据分析的 Kotlin 和 Java 库.