首页 > 解决方案 > 在 Swift 和 Pythonkit 中使用 Python 模块

问题描述

我希望获得一些帮助或澄清在 Swift 中使用 PythonKit 的局限性。好吧,我说的是 PythonKit,我实际上在 Xcode 中安装了 Tensorflow 工具链,因为我无法让 Pythonkit 作为一个单一的依赖项独立工作(MacBook 会在粉丝们试图导入 numpy 的情况下旋转它的轮子)。

无论如何,我想说的是,我可以在 Swift 中使用 Python 模块,这让我更容易开始使用 swift,而不仅仅是 iOS 应用程序。

我的问题是我已经很好地导入了 Python 模块,但不清楚它们将具有多少功能。我认为像 numpy 这样的文件几乎相同,但作为一名科学家,我经常使用 netcdf 文件,所以一直在尝试使用 netCDF4。这很好地导入,我可以很好地加载数据对象和属性等,但我无法得到实际的数组。

这是一个例子:

import PythonKit
PythonLibrary.useVersion(3, 7)

let nc = Python.import("netCDF4")

var Data = nc.Dataset("ncfile path")
var lat_z = Data.variables["lat_z"][:]

[:] 导致 Xcode 发现错误,删除它允许脚本运行,但会导致变量对象而不是数组。我可以在最后添加一些东西来获取属性等,例如 lat_z.long_name 但不确定如何在不使用 [:] 的情况下提取数组

我希望这只是我需要快速学习的语法差异(使用它的早期阶段)还是 PythonKit 的限制?我还没有发现有人经常使用 netcdf4(示例主要是 numpy 和 Matplotlib)如果是这样,在 swift 中使用 python 模块是否存在一些一般限制?

我也试图让 Matplotlib 工作,但我很确定这是由于在 Xcode 中使用了一个没有视图的命令行工具项目,所以它无法向我显示图像是有道理的。

任何指向最新文档的指针和可能的链接都会很棒,似乎发生了一些变化,例如导入 PythonKit 而不是导入 Python。

非常感谢

标签: pythonswifttensorflownetcdf

解决方案


您可以count在 python 可迭代对象上使用该属性,该属性等效于len. 您可以通过两种方式索引 Numpy 数组:(i) 使用 Swift 范围语法和 (ii) 使用 Numpy 范围对象:

import Foundation
import PythonKit

let np = Python.import("numpy")
let array = np.array([1, 2, 3, 4, 5])

print(array)  // [1, 2, 3, 4, 5]

let subArray = array[0..<array.count] 
print(subArray)  // [1, 2, 3, 4, 5]

let subArray2 = array[np.arange(0, 2)]
print(subArray2)  // [1, 2]

// Swift equivalent of Python ":"
let subArray3 = array[...]

您还可以将 numpy 数组转换为 Swift 数组并使用 Swift 方法和下标:

let swiftArray = Array(array)
let swiftSubArray = swiftArray[0..<3]

print(swiftSubArray)  // [1, 2, 3]

请注意,在使用 s 时,您应该更喜欢使用Python.len(...)count属性,PythonObject因为count会导致性能损失,因为它的实现PythonKit不会自动符合Python ObjectRandomAccessCollection因此count是 O(n))。


推荐阅读