In [ ]:
// #@title Licensed under the Apache License, Version 2.0 (the "License"); { display-mode: "form" }
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도 불구하고 공식 영문 문서의 내용과 일치하지 않을 수 있습니다. 이 번역에 개선할 부분이 있다면 tensorflow/docs-l10n 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다. 문서 번역이나 리뷰에 참여하려면 docs-ko@tensorflow.org로 메일을 보내주시기 바랍니다.
In [2]:
// comment so that Colab does not interpret `#if ...` as a comment
#if canImport(PythonKit)
import PythonKit
#else
import Python
#endif
print(Python.version)
기본적으로 import Python
를 하면, 스위프트는 시스템 라이브러리 경로에 따라 설치된 최신 버전의 파이썬을 검색합니다.
특정한 파이썬을 설치하려면, PYTHON_LIBRARY
환경변수에 설치시 제공받은 libpython
공유 라이브러리를 설정합니다. 예를 들어:
export PYTHON_LIBRARY="~/anaconda3/lib/libpython3.7m.so"
정확한 파일명은 파이썬 환경과 플랫폼마다 다를 수 있습니다.
또는 스위프트가 시스템 라이브러리 경로에서 알맞은 파이썬 버전을 찾도록 해서 PYTHON_VERSION
환경변수를 설정할 수 있습니다. PYTHON_LIBRARY
가 PYTHON_VERSION
보다 우선한다는 점을 유의해야 합니다.
또한 코드에서 PYTHON_VERSION
설정과 동일한 기능을 하는 PythonLibrary.useVersion
함수를 호출할 수 있습니다.
In [ ]:
// PythonLibrary.useVersion(2)
// PythonLibrary.useVersion(3, 7)
Note: 파이썬을 임포트한 직후, 파이썬 코드를 호출하기 전에 PythonLibrary.useVersion
을 실행해야 합니다. 이것은 파이썬 버전을 동적으로 바꾸는 데 사용될 수 없습니다.
파이썬 라이브러리 로딩 과정에서 생성되는 디버그 출력을 확인하기 위해서 PYTHON_LOADER_LOGGING=1
를 설정하세요.
스위프트에서 PythonObject
는 파이썬 객체를 나타냅니다.
모든 파이썬 API는 PythonObject
인스턴스를 사용하거나 반환합니다.
스위프트에서 기본형(숫자 및 배열처럼)은 PythonObject
로 전환할 수 있습니다. 몇몇 경우에 (PythonConvertible
인수를 받는 리터럴과 함수의 경우), 변환이 암묵적으로 일어납니다. 스위프트 값을 PythonObject
에 명시적으로 지정하려면 PythonObject
이니셜라이저를 사용합니다.
PythonObject
는 숫자 연산, 인덱싱, 반복을 포함한 많은 표준 연산을 정의합니다.
In [4]:
// 표준 스위프트 자료형을 Python으로 변환합니다.
let pythonInt: PythonObject = 1
let pythonFloat: PythonObject = 3.0
let pythonString: PythonObject = "Hello Python!"
let pythonRange: PythonObject = PythonObject(5..<10)
let pythonArray: PythonObject = [1, 2, 3, 4]
let pythonDict: PythonObject = ["foo": [0], "bar": [1, 2, 3]]
// 파이썬 객체에 표준 연산을 수행합니다.
print(pythonInt + pythonFloat)
print(pythonString[0..<6])
print(pythonRange)
print(pythonArray[2])
print(pythonDict["bar"])
In [5]:
// 파이썬 객체를 다시 스위프트로 변환합니다.
let int = Int(pythonInt)!
let float = Float(pythonFloat)!
let string = String(pythonString)!
let range = Range<Int>(pythonRange)!
let array: [Int] = Array(pythonArray)!
let dict: [String: [Int]] = Dictionary(pythonDict)!
// 표준 연산을 수행합니다.
// 출력은 파이썬과 동일합니다!
print(Float(int) + float)
print(string.prefix(6))
print(range)
print(array[2])
print(dict["bar"]!)
PythonObject
는 많은 표준 스위프트 프로토콜에 대해 적합하도록 정의합니다:
Equatable
Comparable
Hashable
SignedNumeric
Strideable
MutableCollection
ExpressibleBy_Literal
프로토콜이러한 적합성은 형안전(type-safe)하지 않다는 점에 유의해야 합니다: 호환되지 않는 PythonObject
인스턴스에서 프로토콜 기능을 사용하려고 할 때 충돌이 발생할 수 있습니다.
In [6]:
let one: PythonObject = 1
print(one == one)
print(one < one)
print(one + one)
let array: PythonObject = [1, 2, 3]
for (i, x) in array.enumerated() {
print(i, x)
}
튜플을 파이썬에서 스위프트로 변환하려면, 정확한 튜플의 길이를 알아야 합니다.
다음 인스턴스 메서드 중 하나를 호출합니다:
PythonObject.tuple2
PythonObject.tuple3
PythonObject.tuple4
In [7]:
let pythonTuple = Python.tuple([1, 2, 3])
print(pythonTuple, Python.len(pythonTuple))
// 스위프트로 변환합니다.
let tuple = pythonTuple.tuple3
print(tuple)
In [8]:
// `Python.builtins`은 모든 파이썬 내장 객체의 딕셔너리입니다.
_ = Python.builtins
// 파이썬 내장 객체를 사용합니다.
print(Python.type(1))
print(Python.len([1, 2, 3]))
print(Python.sum([1, 2, 3]))
In [9]:
let np = Python.import("numpy")
print(np)
let zeros = np.ones([2, 3])
print(zeros)
안전하게 패키지를 가져오기 위해 예외처리 함수 Python.attemptImport
를 사용하세요.
In [10]:
let maybeModule = try? Python.attemptImport("nonexistent_module")
print(maybeModule)
In [11]:
import TensorFlow
let numpyArray = np.ones([4], dtype: np.float32)
print("Swift type:", type(of: numpyArray))
print("Python type:", Python.type(numpyArray))
print(numpyArray.shape)
In [12]:
// `numpy.ndarray`에서 스위프트 타입으로 변환하는 예제.
let array: [Float] = Array(numpy: numpyArray)!
let shapedArray = ShapedArray<Float>(numpy: numpyArray)!
let tensor = Tensor<Float>(numpy: numpyArray)!
// 스위프트 타입에서 `numpy.ndarray`으로 변환하는 예제.
print(array.makeNumpyArray())
print(shapedArray.makeNumpyArray())
print(tensor.makeNumpyArray())
// dtype이 다른 예제.
let doubleArray: [Double] = Array(numpy: np.ones([3], dtype: np.float))!
let intTensor = Tensor<Int32>(numpy: np.ones([2, 3], dtype: np.int32))!
In [13]:
// 주피터 노트북에 그래프를 표시하기 위한 셀입니다.
// 다른 환경에서는 사용하지 마세요.
%include "EnableIPythonDisplay.swift"
IPythonDisplay.shell.enable_matplotlib("inline")
Out[13]:
In [14]:
let np = Python.import("numpy")
let plt = Python.import("matplotlib.pyplot")
let time = np.arange(0, 10, 0.01)
let amplitude = np.exp(-0.1 * time)
let position = amplitude * np.sin(3 * time)
plt.figure(figsize: [15, 10])
plt.plot(time, position)
plt.plot(time, amplitude)
plt.plot(time, -amplitude)
plt.xlabel("Time (s)")
plt.ylabel("Position (m)")
plt.title("Oscillations")
plt.show()
Out[14]: