나중을 위해 주피터(IPython) 노트북 세션을 절이거나 저장하는 방법
많은 시간이 소요되는 계산을 수행하면서 주피터/아이피톤 노트북에서 더 큰 데이터 분석을 수행하고 있다고 가정해 보겠습니다. 그렇다면 어떤 이유에서인지 주피터 로컬 서버 I를 종료해야 하지만, 시간이 많이 걸리는 모든 계산을 다시 할 필요 없이 나중에 분석 작업으로 돌아가고 싶습니다.
제가 하고 싶은 일은 주피터 세션 전체(모든 팬더 데이터 프레임, np.array, 변수 등)를 저장하거나 저장하여 이전과 동일한 상태로 세션으로 돌아갈 수 있다는 것을 알고 안전하게 서버를 종료할 수 있도록 하는 것입니다.
기술적으로 가능하기는 하나요? 제가 간과한 내장 기능이 있습니까?
답변에 따라 어떤 것이 "경량 피클"이어야 하는지가 있다. 그러나 다음과 같이 변수를 수동으로 저장해야 합니다:
# 기분 전환을 위해 r
내가 원하는 것에 꽤 가깝지만 수동으로 해야 하고 다른 세션을 구별할 수 없기 때문에 유용성이 떨어진다.
(이것을 실제 답으로 제시하기보다는 코멘트를 하고 싶지만, 코멘트를 하기 위해서는 평판이 더 필요합니다.)
대부분의 데이터 유사 변수를 체계적인 방법으로 저장할 수 있습니다. 내가 주로 하는 일은 모든 데이터 프레임, 배열 등을 저장하는 것이다. 노트의 처음에, 선언한다
backup = pd.HDFStore('backup.h5')
생성할 때 새 변수를 저장합니다
backup['var1'] = var1
마지막에, 아마 할 수 있는 좋은 생각일거야
backup.close()
서버를 끄기 전에. 다음에 노트북을 계속 사용하려면:
backup = pd.HDFStore('backup.h5')
var1 = backup['var1']
솔직히 말해서, 나는 ipython 노트북에도 내장된 기능을 선호한다. 이런 식으로 모든 것을 저장할 수는 없고(예를 들어, 오브젝트, 연결), 그렇게 많은 보일러 플레이트 코드로 노트북을 정리하는 것은 어렵다.
이 질문은 다음과 관련이 있습니다:
개별 세포의 결과를 저장하기 위해 는 유용하다.
%%cache longcalc.pkl var1 var2 var3
var1 = longcalculation()
....
노트북을 다시 실행하면 이 셀의 내용이 캐시에서 로드됩니다.
이것은 당신의 질문에 정확하게 대답하는 것은 아니지만, 모든 긴 계산의 결과가 빠르게 복구될 때 충분할 것이다. 이것은 노트북 위에 있는 실행 버튼을 누르는 것의 조합으로 나에게 실행 가능한 해결책이다.
캐시 마법은 전체 노트북의 상태를 저장할 수 없다. 내가 알기로는 아직 "노트북"을 재개할 수 있는 다른 시스템은 없다. 이것은 파이썬 커널의 모든 이력을 저장하는 것을 요구한다. 노트북을 로드하고 커널에 연결한 후 이 정보를 로드해야 합니다.
나는 ()가 너의 질문에 대답을 잘 한다고 생각한다.
노트북 세션을 저장하는 데 사용:
import dill
dill.dump_session('notebook_env.db')
노트북 세션을 복원하는 데 사용:
import dill
dill.load_session('notebook_env.db')
()
절일 수 없는 물체에 대해 실패하고 그러한 물체를 단순히 무시하도록 구성할 수 없기 때문에, 나는 뉴로모픽 엔지니어링 주피터 노트북 클래스 칩 연습에 사용되는 정적 함수 한 쌍을 작성했다.
이 접근 방식은 유용한 게시물을 기반으로 합니다
사용 예:
from ne1 import savevars,loadvars
a=1
b=[2,3]
c='string'
o=(i for i in []) # make generator that cannot be pickled
savevars('testvars')
del a,b,c
loadvars('testvars')
print(a)
print(b)
print(c)
출력:
[INFO]: 2023-10-02 08:28:32,878 - NE1 - saved to testvars.dill variables [ a b c ] (File "/home/ne1/CoACH-labs/ne1.py", line 132, in savevars)
[WARNING]: 2023-10-02 08:28:32,879 - NE1 - could not pickle: ['o'] (File "/home/ne1/CoACH-labs/ne1.py", line 134, in savevars)
[INFO]: 2023-10-02 08:28:32,881 - NE1 - from testvars.dill loaded variables ['a', 'b', 'c'] (File "/home/ne1/CoACH-labs/ne1.py", line 158, in loadvars)
1
[2, 3]
string
아래의 코드를 사용하기 위한 완성도를 위해 로깅 메시지를 포맷하는 커스텀 로거도 넣었습니다. 이 로깅 출력을 원하지 않을 경우 다음으로 대체합니다
기능:
def savevars(filename):
"""
saves all local variables to a file with dill
:param filename: the name of the file. The suffix .dill is added if there is not a suffix already.
"""
if filename is None:
log.error('you must supply a filename')
return
from pathlib import Path
p=Path(filename)
if p.suffix=='': # if suffix is missing add .dill
p = p.parent / (p.name + _DILL)
import inspect,dill
locals=None
frame = inspect.currentframe().f_back
try:
locals = frame.f_locals
finally:
del frame
if locals is None: return
data={}
could_not_pickle=[]
from types import ModuleType
s=f'saved to {p} variables [ '
for k,v in locals.items():
# don't try to pickle any pyplane objects
if k.startswith('_') or k=='tmp' or k=='In' or k=='Out' or hasattr(v, '__call__') \
or isinstance(v,ModuleType) or isinstance(v,logging.Logger):
continue
try:
if not dill.pickles(v):
could_not_pickle.append(k)
continue
except:
could_not_pickle.append(k)
continue
s=s+k+' '
data[k]=v
s=s+']'
try:
with open(p,'wb') as f:
try:
dill.dump(data,f)
log.info(f'{s}')
if len(could_not_pickle)>0:
log.warning(f'could not pickle: {could_not_pickle}')
except TypeError as e:
log.error(f'\n Error: {e}')
except Exception as e:
log.error(f'could not save data to {p}')
그 기능을
def loadvars(filename):
""" Loads variables from file into the current workspace
:param filename: the dill file to load from, e.g. lab1. The suffix .dill is added automatically unless there is already a suffix.
This function loads the variables found in filename into the parent workspace.
"""
import dill
from pathlib import Path
p=Path(filename)
if p.suffix=='': # if suffix is missing add .dill
p = p.parent / (p.name + _DILL)
if not p.exists:
log.error(f'{p} does not exist')
return
try:
with open(p,'rb') as f:
data=dill.load(f)
log.info(f'from {p} loaded variables {list(data.keys())}')
import inspect
try:
frame = inspect.currentframe().f_back # get the workspace frame (jupyter workspace frame)
locals = frame.f_locals # get its local variable dict
for k in data:
try:
locals[k] = data[k] # set a value in it
except Exception as e:
log.error(f'could not set variable {k}')
finally:
del frame
except Exception as e:
log.error(f'could not load; got {e}')
pycharm에서 작동하는 포맷 및 코드라인 하이퍼링크를 사용하는 사용자 지정 Logger:
import logging
# general logger. Produces nice output format with live hyperlinks for pycharm users
# to use it, just call log=get_logger() at the top of your python file
# all these loggers share the same logger name 'Control_Toolkit'
_LOGGING_LEVEL = logging.DEBUG # usually INFO is good
class CustomFormatter(logging.Formatter):
"""Logging Formatter to add colors and count warning / errors"""
# see https://stackoverflow.com/questions/384076/how-can-i-color-python-logging-output/7995762#7995762
# \x1b[ (ESC[) is the CSI introductory sequence for ANSI https://en.wikipedia.org/wiki/ANSI_escape_code
# The control sequence CSI n m, named Select Graphic Rendition (SGR), sets display attributes.
grey = "\x1b[2;37m" # 2 faint, 37 gray
yellow = "\x1b[33;21m"
cyan = "\x1b[0;36m" # 0 normal 36 cyan
green = "\x1b[31;21m" # dark green
red = "\x1b[31;21m" # bold red
bold_red = "\x1b[31;1m"
light_blue = "\x1b[1;36m"
blue = "\x1b[1;34m"
reset = "\x1b[0m"
# File "{file}", line {max(line, 1)}'.replace("\\", "/")
format = '[%(levelname)s]: %(asctime)s - %(name)s - %(message)s (File "%(pathname)s", line %(lineno)d, in %(funcName)s)'
FORMATS = {
logging.DEBUG: grey + format + reset,
logging.INFO: cyan + format + reset,
logging.WARNING: red + format + reset,
logging.ERROR: bold_red + format + reset,
logging.CRITICAL: bold_red + format + reset
}
def format(self, record):
log_fmt = self.FORMATS.get(record.levelno)
formatter = logging.Formatter(log_fmt)
return formatter.format(record).replace("\\", "/") #replace \ with / for pycharm links
def get_logger():
""" Use get_logger to define a logger with useful color output and info and warning turned on according to the global LOGGING_LEVEL.
:returns: the logger.
"""
# logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logger = logging.getLogger('NE1') # tobi changed so all have same name so we can uniformly affect all of them
logger.setLevel(_LOGGING_LEVEL)
# create console handler if this logger does not have handler yet
if len(logger.handlers)==0:
ch = logging.StreamHandler()
ch.setFormatter(CustomFormatter())
logger.addHandler(ch)
return logger
log=get_logger()
'개발하자' 카테고리의 다른 글
Svelte - 액세스 하위 구성 요소의 메서드 (0) | 2023.10.04 |
---|---|
Jupyter 노트북 새 셀 유형 기본값 (0) | 2023.10.04 |
사용자 지정 fastapi 쿼리 매개 변수 유효성 검사 (0) | 2023.10.02 |
python SDK를 통해 코스모스 처리량 업데이트 (0) | 2023.10.02 |
Visual Studio 코드를 사용하여 스크립트 파일 실행 입력 (0) | 2023.10.01 |