การใช้สมุดบันทึก IPython ภายใต้การควบคุมเวอร์ชัน


569

กลยุทธ์ที่ดีในการรักษาโน้ตบุ๊กIPython ให้อยู่ในการควบคุมเวอร์ชัน

รูปแบบสมุดบันทึกค่อนข้างคล้อยตามสำหรับการควบคุมเวอร์ชัน: หากต้องการควบคุมเวอร์ชันโน้ตบุ๊กและเอาท์พุตสิ่งนี้จะทำงานได้ค่อนข้างดี ความรำคาญเกิดขึ้นเมื่อเราต้องการควบคุมการป้อนข้อมูลเฉพาะรุ่นไม่รวมเอาท์พุทของเซลล์ (aka. "build products") ซึ่งอาจเป็น blobs ไบนารีขนาดใหญ่โดยเฉพาะอย่างยิ่งสำหรับภาพยนตร์และแปลง โดยเฉพาะอย่างยิ่งฉันพยายามหาเวิร์กโฟลว์ที่ดีที่:

  • อนุญาตให้ฉันเลือกระหว่างการรวมหรือไม่รวมเอาต์พุต
  • ป้องกันฉันจากการส่งออกโดยไม่ตั้งใจถ้าฉันไม่ต้องการ
  • ช่วยให้ฉันสามารถเก็บเอาท์พุทในรุ่นท้องถิ่นของฉัน
  • อนุญาตให้ฉันดูเมื่อฉันมีการเปลี่ยนแปลงในอินพุตโดยใช้ระบบควบคุมเวอร์ชันของฉัน (เช่นถ้าฉันควบคุมเฉพาะอินพุตเท่านั้น แต่ไฟล์ในเครื่องของฉันมีเอาต์พุตฉันต้องการจะดูว่าอินพุตมีการเปลี่ยนแปลงหรือไม่ ) การใช้คำสั่งสถานะการควบคุมเวอร์ชันจะลงทะเบียนความแตกต่างเสมอเนื่องจากไฟล์ในเครื่องมีเอาต์พุต)
  • อนุญาตให้ฉันอัปเดตสมุดบันทึกการทำงานของฉัน (ซึ่งมีเอาต์พุต) จากสมุดบันทึกที่อัปเดตที่สะอาดแล้ว (update)

ตามที่กล่าวไว้ถ้าฉันเลือกที่จะรวมเอาท์พุท (ซึ่งเป็นที่ต้องการเมื่อใช้nbviewerเป็นต้น) ทุกอย่างก็โอเค ปัญหาคือเมื่อฉันไม่ต้องการรุ่นควบคุมผลลัพธ์ มีเครื่องมือและสคริปต์บางอย่างสำหรับการลอกเอาต์พุตของโน้ตบุ๊ก แต่บ่อยครั้งที่ฉันพบปัญหาต่อไปนี้:

  1. ฉันส่งเวอร์ชันโดยไม่ตั้งใจด้วยเหตุนี้จึงทำให้ที่เก็บข้อมูลของฉันสกปรก
  2. ฉันลบเอาต์พุตเพื่อใช้การควบคุมเวอร์ชัน แต่จะเก็บเอาท์พุทไว้ในเครื่องของฉัน (บางครั้งใช้เวลานานในการสร้างตัวอย่าง)
  3. สคริปต์บางตัวที่ดึงเอาท์พุทเปลี่ยนรูปแบบเล็กน้อยเมื่อเทียบกับCell/All Output/Clearตัวเลือกเมนูดังนั้นจึงสร้างเสียงรบกวนที่ไม่พึงประสงค์ในส่วนต่าง นี่คือคำตอบบางคำตอบ
  4. เมื่อดึงการเปลี่ยนแปลงไปยังไฟล์เวอร์ชั่นใหม่ทั้งหมดฉันต้องหาวิธีที่จะรวมการเปลี่ยนแปลงเหล่านั้นไว้ในสมุดบันทึกการทำงานของฉันโดยไม่ต้องรันใหม่ทุกอย่าง (update)

ฉันได้พิจารณาตัวเลือกหลายอย่างที่ฉันจะกล่าวถึงด้านล่าง แต่ยังไม่พบวิธีแก้ปัญหาที่ครอบคลุมดี โซลูชันที่สมบูรณ์อาจต้องการการเปลี่ยนแปลงบางอย่างกับ IPython หรืออาจต้องพึ่งพาสคริปต์ภายนอกแบบง่าย ๆ ตอนนี้ฉันใช้Mercurialแต่ต้องการโซลูชันที่ทำงานร่วมกับgit ได้ : ทางออกที่ดีที่สุดคือการควบคุมแบบไม่เชื่อเรื่องพระเจ้า

ปัญหานี้มีการพูดคุยหลายครั้ง แต่ไม่มีวิธีการแก้ปัญหาที่ชัดเจนหรือชัดเจนจากมุมมองของผู้ใช้ คำตอบสำหรับคำถามนี้ควรให้กลยุทธ์ที่ชัดเจน ไม่เป็นไรหากต้องการIPythonเวอร์ชันล่าสุด (แม้แต่การพัฒนา) หรือส่วนขยายที่ติดตั้งได้ง่าย

ปรับปรุง:ฉันได้รับการเล่นกับสมุดบันทึกของฉันมีการปรับเปลี่ยนรุ่นซึ่งเลือกที่จะบันทึก.cleanรุ่นทุกประหยัดการใช้ข้อเสนอแนะของเกรกอรี่ Crosswhite สิ่งนี้ตอบสนองข้อ จำกัด ส่วนใหญ่ของฉันได้ แต่ยังไม่ได้แก้ไข:

  1. นี่ยังไม่เป็นโซลูชันมาตรฐาน (ต้องมีการแก้ไขของแหล่งที่มาของ ipython มีวิธีการที่จะบรรลุพฤติกรรมนี้ด้วยส่วนขยายที่เรียบง่ายหรือไม่ต้องการตะขอเกี่ยวแบบประหยัด
  2. ปัญหาที่ฉันมีกับเวิร์กโฟลว์ปัจจุบันกำลังดึงการเปลี่ยนแปลง สิ่งเหล่านี้จะเข้าสู่.cleanไฟล์จากนั้นจะต้องรวมเข้ากับเวอร์ชันการทำงานของฉัน (แน่นอนว่าฉันสามารถรันสมุดบันทึกซ้ำได้ตลอดเวลา แต่อาจเป็นความเจ็บปวดโดยเฉพาะอย่างยิ่งหากผลลัพธ์บางอย่างขึ้นอยู่กับการคำนวณที่ยาวนานการคำนวณแบบขนาน ฯลฯ ) ฉันยังไม่มีความคิดที่ดีเกี่ยวกับวิธีการแก้ไขปัญหานี้เลย . บางทีเวิร์กโฟลว์ที่เกี่ยวข้องกับส่วนขยายอย่างipycacheอาจทำงานได้ แต่ดูเหมือนซับซ้อนเกินไปเล็กน้อย

หมายเหตุ

การเอาออก (ลอก) เอาท์พุท

  • เมื่อโน้ตบุ๊คกำลังทำงานหนึ่งสามารถใช้Cell/All Output/Clearตัวเลือกเมนูสำหรับการเอาออก
  • มีสคริปต์บางตัวสำหรับการลบเอาต์พุตเช่นสคริปต์nbstripout.pyซึ่งลบเอาต์พุต แต่ไม่สร้างเอาต์พุตเดียวกันกับการใช้อินเตอร์เฟสโน้ตบุ๊ก นี่รวมอยู่ในipython / nbconvert repo ในที่สุด แต่สิ่งนี้ได้ถูกปิดระบุว่าตอนนี้การเปลี่ยนแปลงนั้นรวมอยู่ในipython / ipythonแต่ฟังก์ชั่นที่เกี่ยวข้องดูเหมือนว่ายังไม่ได้รวมอยู่ด้วย (อัปเดต)ดังที่ได้กล่าวไว้โซลูชันของ Gregory Crosswhiteแสดงให้เห็นว่านี่เป็นเรื่องง่ายที่จะทำแม้จะไม่มีการเรียกใช้ipython / nbconvertดังนั้นวิธีการนี้อาจใช้การได้หากสามารถเชื่อมต่อได้อย่างถูกต้อง (การเชื่อมต่อเข้ากับระบบควบคุมแต่ละเวอร์ชันอย่างไรก็ตามดูเหมือนจะไม่เป็นความคิดที่ดี - สิ่งนี้ควรเชื่อมโยงกับกลไกของโน้ตบุ๊ค)

กลุ่มข่าว

  • ความคิดเกี่ยวกับรูปแบบโน๊ตบุ๊คสำหรับการควบคุมรุ่น

ประเด็น

ดึงคำขอ


ฟังดูเป็นเรื่องดีที่จะเพิ่มเป็นปัญหาในgithub.com/ipython/ipythonหรือส่งคำขอการดึงที่ช่วยให้คุณบรรลุเป้าหมายนี้
Kyle Kelley

4
เมื่อคุณมีสคริปต์ที่ใช้งานได้สำหรับการลบเอาต์พุตคุณสามารถใช้ตัวกรอง Git "clean" เพื่อนำไปใช้โดยอัตโนมัติก่อนที่จะกระทำ (ดูตัวกรอง clean / smudge)
Matthias

1
@foobarbecue คำถามมีวิธีแก้ไขปัญหาที่ไม่น่าพอใจ: แต่ละข้อมีข้อ จำกัด อย่างน้อยหนึ่งข้อ ตอนนี้ PR 4175 ได้ถูกรวมเข้าด้วยกันแล้วอาจเป็นสูตรที่สมบูรณ์ แต่ก็ยังต้องทำ ทันทีที่ฉันมีเวลาฉันจะทำมัน (เป็นคำตอบ) ถ้าคนอื่นไม่ได้ให้ทางออกที่น่าพอใจในระหว่างนี้
mforbes

1
@ saroele ฉันยังไม่พบวิธีแก้ไขปัญหาที่แนะนำ: ฉันจะไปกับ--scriptตัวเลือก แต่ถูกลบไปแล้ว ฉันรอจนกว่าจะมีการติดตั้งตะขอบันทึกหลังติดตั้ง ( ซึ่งวางแผนไว้ ) ที่ฉันคิดว่าฉันจะสามารถให้โซลูชันที่ยอมรับได้ซึ่งรวมเทคนิคหลายอย่างเข้าด้วยกัน
mforbes

1
@mforbes ดูเหมือนว่า PR นั้นเพิ่งถูกรวมเข้ากับความคิดเห็นของคุณไม่กี่วัน คุณหรือใครบางคนมีความรู้มากกว่าฉันโพสต์คำตอบที่นี่ซึ่งแสดงวิธีการใช้คุณสมบัติใหม่ได้หรือไม่?
KobeJohn

คำตอบ:


124

นี่คือทางออกของฉันด้วยคอมไพล์ อนุญาตให้คุณเพิ่มและกระทำ (และแตกต่าง) ตามปกติ: การดำเนินการเหล่านั้นจะไม่เปลี่ยนแผนผังการทำงานของคุณและในขณะเดียวกันการเรียกใช้โน้ตบุ๊กจะไม่เปลี่ยนประวัติคอมไพล์ของคุณ

แม้ว่าสิ่งนี้สามารถปรับให้เหมาะกับ VCS อื่น ๆ ได้ แต่ฉันรู้ว่ามันไม่เป็นไปตามข้อกำหนดของคุณ (อย่างน้อย VSC agnosticity) ถึงกระนั้นมันก็สมบูรณ์แบบสำหรับฉันและถึงแม้ว่ามันจะไม่มีอะไรยอดเยี่ยมโดยเฉพาะและหลาย ๆ คนก็อาจใช้มันอยู่แล้ว ดังนั้นอาจเป็นประโยชน์กับคนอื่น

  1. บันทึกไฟล์ด้วยเนื้อหานี้ที่ใดที่หนึ่ง (ต่อไปนี้ขอให้เราสมมติ~/bin/ipynb_output_filter.py)
  2. ทำให้สามารถเรียกใช้งานได้ ( chmod +x ~/bin/ipynb_output_filter.py)
  3. สร้างไฟล์~/.gitattributesโดยมีเนื้อหาดังต่อไปนี้

    *.ipynb    filter=dropoutput_ipynb
    
  4. รันคำสั่งต่อไปนี้:

    git config --global core.attributesfile ~/.gitattributes
    git config --global filter.dropoutput_ipynb.clean ~/bin/ipynb_output_filter.py
    git config --global filter.dropoutput_ipynb.smudge cat
    

ทำ!

ข้อ จำกัด :

  • มันทำงานได้เฉพาะกับคอมไพล์
  • ในคอมไพล์ถ้าคุณอยู่ในสาขาsomebranchและคุณทำgit checkout otherbranch; git checkout somebranchคุณมักจะคาดหวังว่าต้นไม้ทำงานจะไม่เปลี่ยนแปลง ที่นี่แทนคุณจะสูญเสียผลลัพธ์และจำนวนเซลล์ของสมุดบันทึกที่มีแหล่งที่มาแตกต่างกันระหว่างสองสาขา
  • โดยทั่วไปแล้วเอาต์พุตไม่ได้เป็นเวอร์ชันเลยเช่นเดียวกับโซลูชันของ Gregory เพื่อไม่เพียงทิ้งทุกครั้งที่คุณทำสิ่งใดก็ตามที่เกี่ยวข้องกับการชำระเงินวิธีการอาจเปลี่ยนแปลงได้โดยจัดเก็บไว้ในไฟล์แยกต่างหาก (แต่สังเกตว่าในขณะที่รันโค้ดข้างต้นจะไม่รู้จักรหัสการคอมมิท!) และอาจเป็นเวอร์ชันได้ (แต่โปรดสังเกตว่าสิ่งนี้จะต้องมีอะไรมากกว่าgit commit notebook_file.ipynbนั้นแม้ว่าอย่างน้อยมันก็ควรจะเป็นgit diff notebook_file.ipynbอิสระจาก base64 ขยะ)
  • ที่กล่าวโดยบังเอิญถ้าคุณทำรหัสดึง (เช่นมุ่งมั่นโดยคนอื่นไม่ได้ใช้วิธีการนี้) ซึ่งมีเอาท์พุทบางส่วนเอาท์พุทจะได้รับการตรวจสอบตามปกติ เฉพาะผลผลิตที่ผลิตในท้องถิ่นเท่านั้นที่จะหายไป

วิธีการแก้ปัญหาของฉันสะท้อนให้เห็นถึงความจริงที่ว่าฉันไม่ชอบที่จะสร้างสิ่งต่าง ๆ ตามรุ่น - สังเกตว่าการผสานที่เกี่ยวข้องกับผลผลิตนั้นเกือบจะรับประกันว่าจะทำให้ผลลัพธ์หรือผลผลิตของคุณหรือทั้งสองอย่างถูกต้อง

แก้ไข:

  • ถ้าคุณใช้วิธีการแก้ปัญหาตามที่ฉันแนะนำมัน - นั่นคือทั่วโลก - คุณจะมีปัญหาในกรณีสำหรับ repo git บางอย่างที่คุณต้องการออกรุ่น ดังนั้นหากคุณต้องการปิดการใช้งานการกรองผลลัพธ์สำหรับพื้นที่เก็บข้อมูล git ที่เจาะจงเพียงแค่สร้างไฟล์. git / info / attributesไว้ข้างใน

    **. ipynb filter =

เป็นเนื้อหา เห็นได้ชัดว่าในทางเดียวกันก็เป็นไปได้ที่จะทำตรงข้าม: เปิดใช้งานกรองเฉพาะสำหรับพื้นที่เก็บข้อมูลที่เฉพาะเจาะจง

  • ตอนนี้รหัสจะถูกเก็บรักษาไว้ในrepo git

  • หากคำแนะนำข้างต้นส่งผลให้ ImportErrors ลองเพิ่ม "ipython" หน้าพา ธ ของสคริปต์:

    git config --global filter.dropoutput_ipynb.clean ipython ~/bin/ipynb_output_filter.py
    

แก้ไข : พฤษภาคม 2016 (การปรับปรุงกุมภาพันธ์ 2017): มีหลายทางเลือกไปยังสคริปต์ของฉัน - เพื่อความสมบูรณ์และนี่คือรายชื่อของผู้ที่ฉันรู้: nbstripout ( อื่น ๆ สายพันธุ์ ) nbstrip , JQ


2
คุณจะจัดการกับปัญหาของการรวมการเปลี่ยนแปลงที่คุณดึงได้อย่างไร คุณเพิ่งอยู่กับต้องสร้างทั้งหมดเอาท์พุท? (ฉันคิดว่านี่เป็นการแสดงให้เห็นถึงข้อ จำกัด ที่สองของคุณ)
mforbes

1
@zhermes: เวอร์ชั่นเพิ่มเติมนี้น่าจะใช้ได้
Pietro Battiston

1
มีวิธีใช้ตัวกรอง git นี้กับเครื่องมือ diff ภายนอกหรือไม่? ตัวกรองจะถูกนำไปใช้ถ้าฉันใช้เครื่องมือบรรทัดคำสั่งปกติ แต่ไม่ได้ใช้ถ้าฉันใช้ meld เป็นเครื่องมือ diff stackoverflow.com/q/30329615/578770
FA

1
เพื่อหลีกเลี่ยงการได้รับImportErrorฉันมีการเปลี่ยนแปลงข้างต้นเพื่อให้ทำงานได้โดยใช้ ipython:git config --global filter.dropoutput_ipynb.clean ipython ~/bin/ipynb_output_filter.py
chris838

1
วิธีแก้ปัญหาที่น่ากลัว Pietro ขอบคุณ :) ฉันเปลี่ยน 2 สิ่งเมื่อใช้สคริปต์ของคุณในกรณีของฉัน: 1) ฉันต้องการประกาศตัวกรองใน. gitattributes ในรากของ repo ซึ่งตรงข้ามกับ~/.gitattributesคนอื่น ๆ มีตัวกรองเดียวกันกับที่ฉันทำ 2 ) ฉันกำหนด regexp เป็นworkdir/**/*.ipynb filter=dropoutput_ipynbและฉันวางสมุดบันทึกส่วนใหญ่ของฉันใน workdir / => ถ้าฉันยังต้องการที่จะผลักดันโน้ตบุ๊คที่มีเอาท์พุทและเพลิดเพลินไปกับการแสดงผลที่คั่นหน้าได้ใน github ฉันเพิ่งวางมันไว้ข้างนอกโฟลเดอร์
Svend

63

เรามีโครงการความร่วมมือที่ผลิตภัณฑ์เป็นสมุดบันทึก Jupyter และเราใช้วิธีการในช่วงหกเดือนที่ผ่านมาซึ่งใช้งานได้ดี: เราเปิดใช้งานการบันทึก.pyไฟล์โดยอัตโนมัติและติดตามทั้ง.ipynbไฟล์และ.pyไฟล์

ด้วยวิธีนี้ถ้ามีคนต้องการดู / ดาวน์โหลดสมุดบันทึกล่าสุดที่พวกเขาสามารถทำได้ผ่าน github หรือ nbviewer และถ้ามีคนต้องการดูว่ารหัสสมุดบันทึกมีการเปลี่ยนแปลงอย่างไรพวกเขาสามารถดูการเปลี่ยนแปลงของ.pyไฟล์ได้

สำหรับJupyterเซิร์ฟเวอร์โน้ตบุ๊กสามารถทำได้โดยเพิ่มบรรทัด

import os
from subprocess import check_call

def post_save(model, os_path, contents_manager):
    """post-save hook for converting notebooks to .py scripts"""
    if model['type'] != 'notebook':
        return # only do this for notebooks
    d, fname = os.path.split(os_path)
    check_call(['jupyter', 'nbconvert', '--to', 'script', fname], cwd=d)

c.FileContentsManager.post_save_hook = post_save

ไปที่jupyter_notebook_config.pyไฟล์และรีสตาร์ทเซิร์ฟเวอร์โน้ตบุ๊ค

หากคุณไม่แน่ใจว่าในการที่จะหาไดเรกทอรีของjupyter_notebook_config.pyแฟ้มที่คุณสามารถพิมพ์และถ้าคุณไม่พบแฟ้มที่มีคุณสามารถสร้างได้โดยการพิมพ์jupyter --config-dirjupyter notebook --generate-config

สำหรับIpython 3เซิร์ฟเวอร์โน้ตบุ๊กสามารถทำได้โดยเพิ่มบรรทัด

import os
from subprocess import check_call

def post_save(model, os_path, contents_manager):
    """post-save hook for converting notebooks to .py scripts"""
    if model['type'] != 'notebook':
        return # only do this for notebooks
    d, fname = os.path.split(os_path)
    check_call(['ipython', 'nbconvert', '--to', 'script', fname], cwd=d)

c.FileContentsManager.post_save_hook = post_save

ไปที่ipython_notebook_config.pyไฟล์และรีสตาร์ทเซิร์ฟเวอร์โน้ตบุ๊ค บรรทัดเหล่านี้มาจากปัญหา github ที่@minrk ให้ไว้และ @dror รวมไว้ในคำตอบ SO ของเขาเช่นกัน

สำหรับIpython 2เซิร์ฟเวอร์โน้ตบุ๊กสามารถทำได้โดยเริ่มต้นเซิร์ฟเวอร์โดยใช้:

ipython notebook --script

หรือโดยการเพิ่มบรรทัด

c.FileNotebookManager.save_script = True

ไปที่ipython_notebook_config.pyไฟล์และรีสตาร์ทเซิร์ฟเวอร์โน้ตบุ๊ค

หากคุณไม่แน่ใจว่าในการที่จะหาไดเรกทอรีของipython_notebook_config.pyแฟ้มที่คุณสามารถพิมพ์และถ้าคุณไม่พบแฟ้มที่มีคุณสามารถสร้างได้โดยการพิมพ์ipython locate profile defaultipython profile create

นี่คือโครงการของเราบน GitHub ที่ใช้วิธีนี้และนี่เป็นตัวอย่าง GitHub ของการสำรวจการเปลี่ยนแปลงล่าสุดของโน๊ตบุ๊ค

เรามีความสุขมากกับสิ่งนี้


1
ขอขอบคุณสำหรับหลักฐานเพิ่มเติมที่ใช้--scriptในทางปฏิบัติแล้ว ปัญหาของเรื่องนี้ก็คือว่าโน้ตบุ๊คจริงอาจมีขนาดใหญ่หากเก็บภาพไว้ ทางออกที่ดีที่สุดสำหรับวิธีนี้อาจใช้บางสิ่งบางอย่างเช่นgit-annexเพื่อติดตามเฉพาะโน้ตบุ๊กรุ่นล่าสุด
mforbes

ใน Ipython 3.x ค่า--scriptไม่ได้รับการสนับสนุน ipython.org/ipython-doc/3/whatsnew/version3.html
Dror

ขอบคุณ @dror ฉันได้อัปเดตคำตอบของฉันเพื่อมอบโซลูชัน ipython 3.x ของ minrk ตามที่คุณให้ไว้ที่นี่ด้วย
Rich Signell

10
อัปเดต:โซลูชันนี้ใช้งานไม่ได้ใน iPython เวอร์ชัน 4 เนื่องจาก "The Big Split" ของ Jupyter จาก iPython ในการปรับโซลูชันนี้เป็นเวอร์ชัน 4 ให้ใช้คำสั่งjupyter notebook --generate-configเพื่อสร้างไฟล์ปรับแต่ง คำสั่งjupyter --config-dirค้นหาว่าไดเรกทอรีใดที่มีไฟล์กำหนดค่า และข้อมูลโค้ดที่กำหนดโดย @Rich jupyter_notebook_config.pyควรจะเพิ่มไฟล์ที่ชื่อว่า ส่วนที่เหลือทำงานเหมือนก่อน
mobius dumpling

2
นอกจากจุดโดย @mobiusdumpling ให้แทนที่check_call(['ipython'ด้วยcheck_call(['jupyter'มิฉะนั้นคุณจะได้รับคำเตือนที่ipython nbconvertเลิกใช้แล้วและคุณควรใช้jupyter nbconvertแทน (Jupyter v4.1.0, iPython v4.1.2)
cutculus

36

ฉันได้สร้างขึ้นnbstripoutตามส่วนสำคัญ MinRKsซึ่งรองรับทั้ง Git และ Mercurial (ขอบคุณ mforbes) มันมีจุดมุ่งหมายที่จะใช้แบบสแตนด์อโลนทั้งในบรรทัดคำสั่งหรือเป็นตัวกรองซึ่งเป็นได้อย่างง่ายดาย (UN) ที่ติดตั้งในพื้นที่เก็บข้อมูลในปัจจุบันผ่านทาง/nbstripout installnbstripout uninstall

รับจากPyPIหรือเพียงแค่

pip install nbstripout

ฉันกำลังพิจารณาเวิร์กโฟลว์ที่ฉันเก็บทั้ง. ipnb และ. py ที่สอดคล้องกันที่สร้างขึ้นโดยอัตโนมัติโดยใช้ hooks บันทึกหลังที่อธิบายไว้ข้างต้น ฉันต้องการใช้. py สำหรับ diffs - จะสามารถล้างไฟล์. py จากเคาน์เตอร์ดำเนินการของเซลล์ (# In [1] เปลี่ยนเป็น In [*]) เพื่อไม่ให้ยุ่งเหยิง diffs หรือฉันควร สร้างสคริปต์อย่างง่ายสำหรับการทำเช่นนั้น?
Krzysztof Słowiński

1
@ KrzysztofSłowiński nbstripoutไม่ไม่รองรับกรณีการใช้งานนี้ได้อย่างง่ายดายเนื่องจากอาศัยรูปแบบ JSON ของโน้ตบุ๊ก คุณน่าจะดีกว่าการเขียนสคริปต์เฉพาะสำหรับกรณีการใช้งานของคุณ
kynan

13

นี่คือโซลูชันใหม่จาก Cyrille Rossant สำหรับ IPython 3.0 ซึ่งยังคงอยู่กับไฟล์ที่ทำเครื่องหมายแทนที่จะเป็นไฟล์ ipymd ที่ใช้ json:

https://github.com/rossant/ipymd


ยังไม่สนับสนุน Jupyter ดูเหมือนว่า
K. -Michael Aye

ฉันใช้ ipymd เรียบร้อยแล้วกับ Jupyter ล่าสุด - คุณได้รับปัญหาเฉพาะหรือข้อความแสดงข้อผิดพลาดหรือไม่?
Cyrille Rossant

13

หลังจากไม่กี่ปีของการลบเอาต์พุตในโน้ตบุ๊กฉันพยายามหาวิธีที่ดีกว่า ตอนนี้ฉันใช้Jupytextซึ่งเป็นส่วนเสริมสำหรับทั้ง Jupyter Notebook และ Jupyter Lab ที่ฉันได้ออกแบบไว้

Jupytext สามารถแปลงสมุดบันทึก Jupyter เป็นรูปแบบข้อความต่างๆ (สคริปต์, Markdown และ R Markdown) และตรงกันข้าม นอกจากนี้ยังมีตัวเลือกในการจับคู่สมุดบันทึกให้เป็นหนึ่งในรูปแบบเหล่านี้และทำการซิงโครไนซ์การนำเสนอทั้งสองของสมุดบันทึกโดยอัตโนมัติ ( .ipynbและ.md/.py/.Rไฟล์)

ให้ฉันอธิบายวิธี Jupytext ตอบคำถามข้างต้น:

อนุญาตให้ฉันเลือกระหว่างการรวมหรือไม่รวมเอาต์พุต

.md/.py/.Rไฟล์มีเพียงเซลล์ป้อนข้อมูล คุณควรติดตามไฟล์นี้อยู่เสมอ รุ่น.ipynbไฟล์เท่านั้นถ้าคุณต้องการติดตามผล

ป้องกันฉันจากการส่งออกโดยไม่ตั้งใจถ้าฉันไม่ต้องการ

เพิ่ม*.ipynbไปยัง.gitignore

ช่วยให้ฉันสามารถเก็บเอาท์พุทในรุ่นท้องถิ่นของฉัน

ขาออกจะถูกเก็บไว้ใน (ท้องถิ่น) .ipynbไฟล์

อนุญาตให้ฉันดูเมื่อฉันมีการเปลี่ยนแปลงในอินพุตโดยใช้ระบบควบคุมเวอร์ชันของฉัน (เช่นถ้าฉันควบคุมเฉพาะอินพุตเท่านั้น แต่ไฟล์ในเครื่องของฉันมีเอาต์พุตฉันต้องการจะดูว่าอินพุตมีการเปลี่ยนแปลงหรือไม่ ) การใช้คำสั่งสถานะการควบคุมเวอร์ชันจะลงทะเบียนความแตกต่างเสมอเนื่องจากไฟล์ในเครื่องมีเอาต์พุต)

diff .py/.Rหรือ.mdไฟล์คือสิ่งที่คุณกำลังมองหา

อนุญาตให้ฉันอัปเดตสมุดบันทึกการทำงานของฉัน (ซึ่งมีเอาต์พุต) จากสมุดบันทึกที่อัปเดตที่สะอาดแล้ว (update)

ดึงฉบับแก้ไขล่าสุด.py/.Rหรือ.mdไฟล์และรีเฟรชสมุดบันทึกของคุณใน Jupyter (Ctrl + R) คุณจะได้รับเซลล์อินพุตล่าสุดจากไฟล์ข้อความโดยมีเอาต์พุตที่ตรงกันจาก.ipynbไฟล์ เคอร์เนลไม่ได้รับผลกระทบซึ่งหมายความว่าตัวแปรภายในเครื่องของคุณได้รับการเก็บรักษาไว้ - คุณสามารถทำงานต่อไปได้ตามที่คุณทิ้งไว้

สิ่งที่ฉันชอบ Jupytext คือสามารถแก้ไขโน๊ตบุ๊ค (ภายใต้รูปแบบของ ไฟล์.py/.Rหรือ.md) ใน IDE ที่คุณชื่นชอบ ด้วยวิธีการนี้การปรับโครงสร้างโน้ตบุ๊คให้กลายเป็นเรื่องง่าย เมื่อเสร็จแล้วคุณต้องรีเฟรชสมุดบันทึกใน Jupyter

หากคุณต้องการลอง: ติดตั้ง Jupytext ด้วยpip install jupytextและรีสตาร์ท Jupyter Notebook หรือ Lab editor ของคุณ เปิดสมุดบันทึกที่คุณต้องการควบคุมเวอร์ชันและจับคู่กับไฟล์ Markdown (หรือสคริปต์) โดยใช้เมนู Jupytext ในสมุดบันทึก Jupyter (หรือคำสั่ง Jupytext ใน Jupyter Lab) บันทึกสมุดบันทึกของคุณและคุณจะได้รับทั้งสองไฟล์: แบบดั้งเดิม.ipynbรวมถึงการแสดงข้อความตามสัญญาของสมุดบันทึกซึ่งเหมาะอย่างยิ่งสำหรับการควบคุมเวอร์ชัน!

สำหรับผู้ที่อาจจะสนใจ: Jupytext ยังมีอยู่ในบรรทัดคำสั่ง


13

อัปเดต : ตอนนี้คุณทำได้แก้ไขไฟล์ Jupyter Notebook ได้โดยตรงใน Visual Studio Code คุณสามารถเลือกที่จะแก้ไขสมุดบันทึกหรือไฟล์ไพ ธ อนที่แปลงแล้ว

ในที่สุดฉันก็พบวิธีที่สร้างสรรค์และเรียบง่ายในการทำให้ Jupyter และ Git เล่นด้วยกันได้อย่างดี ฉันยังอยู่ในขั้นตอนแรก แต่ฉันคิดว่ามันดีกว่าโซลูชันที่ซับซ้อนอื่น ๆ ทั้งหมด

Visual Studio Codeเป็นโปรแกรมแก้ไขโค้ดโอเพ่นซอร์สและเด็ดจาก Microsoft มันมีนามสกุลไพ ธ อนที่ยอดเยี่ยมที่ตอนนี้อนุญาตให้คุณนำเข้า Jupyter Notebookเป็นรหัสหลาม ตอนนี้คุณยังสามารถโดยตรงแก้ไข Jupyter โน้ตบุ๊ค

หลังจากที่คุณนำเข้าโน๊ตบุ๊คของคุณไปยังไฟล์ไพ ธ อนรหัสและมาร์คดาวน์ทั้งหมดจะรวมเข้าด้วยกันในไฟล์ไพ ธ อนสามัญพร้อมเครื่องหมายพิเศษในความคิดเห็น คุณสามารถดูในภาพด้านล่าง:

เครื่องมือแก้ไข VSCode พร้อมโน้ตบุ๊กที่แปลงเป็นไพ ธ อน

ไฟล์ไพ ธ อนของคุณมีเนื้อหาของเซลล์อินพุตโน้ตบุ๊ก ผลลัพธ์จะถูกสร้างขึ้นในหน้าต่างแยก คุณมีรหัสบริสุทธิ์ในสมุดบันทึกมันจะไม่เปลี่ยนแปลงในขณะที่คุณรันมัน ไม่มีการปะปนกับรหัสของคุณ ไม่มีรูปแบบที่ไม่สามารถเข้าใจได้ของ JSON ที่แปลกประหลาดในการวิเคราะห์ความแตกต่างของคุณ

เพียงรหัสหลามบริสุทธิ์ที่คุณสามารถระบุความแตกต่างทุกอย่างได้อย่างง่ายดาย

ฉันไม่จำเป็นต้องทำเวอร์ชัน.ipynbไฟล์ของฉันอีกต่อไป ฉันสามารถใส่เส้น*.ipynb.gitignore

ต้องการสร้างสมุดบันทึกเพื่อเผยแพร่หรือแบ่งปันกับใครบางคน? ไม่มีปัญหาเพียงคลิกที่ปุ่มส่งออกในหน้าต่างหลามแบบโต้ตอบ

การส่งออกไฟล์หลามเป็นรูปแบบโน๊ตบุ๊ค

หากคุณกำลังแก้ไขโน้ตบุ๊กโดยตรงตอนนี้จะมีไอคอน Convert and save to a python scriptหากคุณกำลังแก้ไขโน้ตบุ๊คโดยตรงขณะนี้ไอคอน ไอคอน Jupyter ในรหัส Visual Studio

นี่คือภาพหน้าจอของโน้ตบุ๊กภายใน Visual Studio Code:

การแก้ไขสมุดบันทึกภายใน VSCode

ฉันใช้มันแค่วันเดียว แต่ในที่สุดฉันก็สามารถใช้ Jupyter กับ Git ได้อย่างมีความสุข

PS: การกรอกโค้ด VSCode ดีกว่า Jupyter มาก


12

(2017-02)

กลยุทธ์

  • on_commit ():
    • ดึงเอาท์พุท> name.ipynb ( nbstripout,)
    • ดึงเอาท์พุท> name.clean.ipynb ( nbstripout,)
    • เสมอnbconvertกับ python: name.ipynb.py ( nbconvert)
    • แปลงเป็น markdown เสมอ: name.ipynb.md ( nbconvert, ipymd)
  • vcs.configure ():
    • คอมไพล์ไฟล์, mergetool: nbdiff และ nbmerge จาก nbdime

เครื่องมือ

  • nbstripout: ดึงเอาท์พุทจากโน้ตบุ๊ก
  • ipynb_output_filter: ดึงเอาท์พุทจากโน้ตบุ๊ก
  • ipymd: แปลงระหว่าง {Jupyter, Markdown, O'Reilly Atlas Markdown, OpenDocument, .py}
  • nbdime: "เครื่องมือสำหรับการกระจายและการรวมสมุดบันทึก Jupyter" (2015)
    • src: https://github.com/jupyter/nbdime
    • เอกสาร: http://nbdime.readthedocs.io/
      • nbdiff: เปรียบเทียบโน้ตบุ๊กด้วยวิธีที่เป็นมิตร
      • nbmerge: ผสานสามทางของโน้ตบุ๊คที่มีการแก้ไขข้อขัดแย้งอัตโนมัติ
        • nbdime nbmerge ทำงานเป็นเครื่องมือคอมไพล์ผสาน
      • nbdiff-web: แสดงให้คุณเห็นถึงความแตกต่างของโน้ตบุ๊ก
      • nbmerge-web: ให้เครื่องมือผสานสามทางบนเว็บสำหรับโน้ตบุ๊ก
      • nbshow: นำเสนอสมุดบันทึกเดียวในวิธีที่เป็นมิตรกับ terminal

11

คำตอบที่ได้รับความนิยมมากในปี 2559 นั้นเป็นวิธีที่ไม่สอดคล้องกันเมื่อเปรียบเทียบกับวิธีที่ดีกว่าในปี 2019

มีหลายตัวเลือกที่ดีที่สุดที่ตอบคำถามคือ Jupytext

Jupytext

รับบทความเกี่ยวกับข้อมูลวิทยาศาสตร์ใน Jupytext

วิธีการทำงานกับการควบคุมเวอร์ชันคือคุณใส่ทั้งไฟล์. py และ. ipynb ในการควบคุมเวอร์ชัน ดู. py หากคุณต้องการให้อินพุตต่างกันดูที่. ipynb หากคุณต้องการเอาต์พุตที่เรนเดอร์ล่าสุด

กล่าวถึงเด่น: สตูดิโอ VS, nbconvert, nbdime, ไฮโดรเจน

ฉันคิดว่ามีงานอีกเล็กน้อย VS สตูดิโอและ / หรือไฮโดรเจน (หรือคล้ายกัน) จะกลายเป็นผู้เล่นที่โดดเด่นในการแก้ปัญหาสำหรับกระบวนการทำงานนี้


9

เพิ่งเจอ "jupytext" ซึ่งดูเหมือนเป็นโซลูชั่นที่สมบูรณ์แบบ มันสร้างไฟล์. py จากโน้ตบุ๊กแล้วทำการซิงค์ทั้งคู่ คุณสามารถควบคุมเวอร์ชัน diff และผสานอินพุตผ่านไฟล์. py ได้โดยไม่สูญเสียเอาต์พุต เมื่อคุณเปิดโน้ตบุ๊กจะใช้. py สำหรับเซลล์อินพุตและ. ipynb สำหรับเอาต์พุต และถ้าคุณต้องการที่จะรวมเอาท์พุทในคอมไพล์แล้วคุณก็สามารถเพิ่ม ipynb

https://github.com/mwouts/jupytext


9

เนื่องจากมีกลยุทธ์และเครื่องมือมากมายในการจัดการการควบคุมเวอร์ชันสำหรับโน้ตบุ๊กฉันจึงพยายามสร้างแผนผังการไหลเพื่อเลือกกลยุทธ์ที่เหมาะสม (สร้างเมษายน 2019)

โฟลว์การตัดสินใจเพื่อเลือกกลยุทธ์การควบคุมเวอร์ชัน


8

ในฐานะที่เป็นแหลมออกโดยที่จะเลิกใน--script 3.xวิธีการนี้สามารถนำมาใช้โดยใช้โพสต์บันทึกเบ็ด โดยเฉพาะเพิ่มสิ่งต่อไปนี้ในipython_notebook_config.py:

import os
from subprocess import check_call

def post_save(model, os_path, contents_manager):
    """post-save hook for converting notebooks to .py scripts"""
    if model['type'] != 'notebook':
        return # only do this for notebooks
    d, fname = os.path.split(os_path)
    check_call(['ipython', 'nbconvert', '--to', 'script', fname], cwd=d)

c.FileContentsManager.post_save_hook = post_save

รหัสจะนำมาจาก# 8009


ขอขอบคุณที่สาธิตการใช้ตะขอหลังการบันทึก น่าเสียดายที่การกล่าวกลับจาก.pyไฟล์ไปยังโน้ตบุ๊กเป็นปัญหาดังนั้นนี่จึงไม่ใช่วิธีแก้ปัญหาที่สมบูรณ์ (ชนิดของฉันหวังว่ามันจะได้รับในขณะที่มันเป็นสิ่งที่ดีมากที่จะ diff .pyไฟล์แทนโน๊ตบุ๊คบางทีใหม่. โน๊ตบุ๊ค diffคุณลักษณะจะเป็นประโยชน์.
mforbes

1
ขอบคุณ! ตอนนี้ฉันใช้เคล็ดลับนี้เพื่อทำให้เกิด--scriptพฤติกรรมซ้ำโดยไม่คำนึงถึงการควบคุมเวอร์ชัน ฉันมีปัญหาบางอย่างในตอนแรกดังนั้นในกรณีที่ฉันสามารถบันทึกบางคนเวลา: 1) หากipython_notebook_config.pyหายไปจากโฟลเดอร์โปรไฟล์เรียกใช้ipython profile createเพื่อสร้างมัน 2) ถ้าดูเหมือนว่า post-save-hook ถูกละเว้นให้รัน ipython ด้วย--debugเพื่อวินิจฉัยปัญหา 3) ถ้าสคริปต์ไม่ผิดพลาดImportError: No module named mistune- ติดตั้งง่าย pip install mistuneminstue:
Joe

7

น่าเสียดายที่ฉันไม่ค่อยรู้เรื่อง Mercurial มากนัก แต่ฉันสามารถมอบวิธีแก้ปัญหาที่เป็นไปได้ให้คุณซึ่งทำงานกับ Git ด้วยความหวังว่าคุณจะสามารถแปลคำสั่ง Git ของฉันเป็น Mercurial ที่เทียบเท่าได้

สำหรับพื้นหลังใน Git addคำสั่งจะเก็บการเปลี่ยนแปลงที่เกิดขึ้นกับไฟล์ลงในพื้นที่จัดเตรียม เมื่อคุณทำสิ่งนี้แล้วการเปลี่ยนแปลงใด ๆ ที่ตามมาของไฟล์จะถูกละเว้นโดย Git ยกเว้นว่าคุณบอกให้ทำขั้นตอนดังกล่าว ดังนั้นสคริปต์ต่อไปนี้ซึ่งสำหรับแต่ละไฟล์ที่กำหนดแถบออกทั้งหมดของoutputsและprompt_number sectionsขั้นตอนไฟล์ปล้นแล้วคืนค่าเดิม:

หมายเหตุ:หากการทำงานนี้ทำให้คุณได้รับข้อความแสดงข้อผิดพลาดเช่นImportError: No module named IPython.nbformatนั้นใช้เรียกใช้สคริปต์แทนipythonpython

from IPython.nbformat import current
import io
from os import remove, rename
from shutil import copyfile
from subprocess import Popen
from sys import argv

for filename in argv[1:]:
    # Backup the current file
    backup_filename = filename + ".backup"
    copyfile(filename,backup_filename)

    try:
        # Read in the notebook
        with io.open(filename,'r',encoding='utf-8') as f:
            notebook = current.reads(f.read(),format="ipynb")

        # Strip out all of the output and prompt_number sections
        for worksheet in notebook["worksheets"]:
            for cell in worksheet["cells"]:
               cell.outputs = []
               if "prompt_number" in cell:
                    del cell["prompt_number"]

        # Write the stripped file
        with io.open(filename, 'w', encoding='utf-8') as f:
            current.write(notebook,f,format='ipynb')

        # Run git add to stage the non-output changes
        print("git add",filename)
        Popen(["git","add",filename]).wait()

    finally:
        # Restore the original file;  remove is needed in case
        # we are running in windows.
        remove(filename)
        rename(backup_filename,filename)

git commitเมื่อสคริปต์ที่ได้รับการทำงานบนไฟล์ที่มีการเปลี่ยนแปลงที่คุณต้องการที่จะกระทำการเรียกใช้เพียง


ขอบคุณสำหรับคำแนะนำ Mercurial ไม่ได้มีพื้นที่จัดเตรียมเช่นคอมไพล์ (แม้ว่าใคร ๆ ก็สามารถใช้คิวคิวคิวเรียลเพื่อวัตถุประสงค์นี้) ในระหว่างนี้ฉันพยายามเพิ่มรหัสนี้ลงใน save hook ที่บันทึกรุ่นที่สะอาดพร้อมกับ.cleanส่วนขยาย น่าเสียดายที่ฉันไม่สามารถเห็นวิธีการทำเช่นนี้ได้โดยไม่ต้องแก้ไข IPython โดยตรง (แม้ว่าการเปลี่ยนแปลงนี้จะค่อนข้างเล็กน้อย) ฉันจะเล่นกับสิ่งนี้เป็นระยะเวลาหนึ่งและดูว่าเหมาะสมกับความต้องการทั้งหมดของฉันหรือไม่
mforbes

6

ฉันใช้วิธีปฏิบัติอย่างมาก ซึ่งทำงานได้ดีสำหรับโน้ตบุ๊กหลาย ๆ เครื่องที่หลาย ๆ ด้าน และยังช่วยให้ฉันสามารถ 'โอนย้าย' สมุดบันทึกไปรอบ ๆ มันทำงานได้ทั้ง Windows สำหรับ Unix / MacOS
อัลคิดว่ามันง่ายคือแก้ปัญหาข้างต้น ...

แนวคิด

โดยทั่วไปจะไม่ได้ติดตาม.ipnyb-Files เพียงที่สอดคล้อง.py-Files
โดยการเริ่มต้นnotebook-serverด้วย--scriptตัวเลือกไฟล์นั้นจะถูกสร้าง / บันทึกโดยอัตโนมัติเมื่อบันทึกโน้ตบุ๊ก

ไฟล์เหล่านั้น.pyมีอินพุตทั้งหมด ไม่ใช่รหัสจะถูกบันทึกลงในความคิดเห็นเช่นเดียวกับเส้นขอบของเซลล์ ไฟล์เหล่านั้นสามารถอ่าน / นำเข้า (และลาก) ลงในโน้ตบุ๊กเซิร์ฟเวอร์เพื่อสร้างสมุดบันทึกใหม่ เฉพาะเอาต์พุตที่หายไป จนกว่าจะมีการเรียกใช้อีกครั้ง

ส่วนตัวฉันใช้Mercurialเพื่อติดตาม.pyไฟล์; และใช้คำสั่งปกติ (บรรทัดคำสั่ง) เพื่อเพิ่มเช็คอิน (ect) สำหรับสิ่งนั้น VCS อื่น ๆ ส่วนใหญ่จะอนุญาตให้ทำได้

มันง่ายต่อการติดตามประวัติศาสตร์ตอนนี้; .pyมีขนาดเล็กต้นฉบับเดิมและง่ายต่อการ diff นาน ๆ ครั้งเราจำเป็นต้องมีการโคลน (เพียงสาขา; เริ่มโน๊ตบุ๊คที่สองที่มี) หรือรุ่นที่เก่ากว่า (ตรวจสอบมันออกและนำเข้าสู่เซิร์ฟเวอร์โน๊ตบุ๊ค) ฯลฯ

เคล็ดลับและลูกเล่น

  • เพิ่ม* .ipynbที่ ' .hgignore ' ดังนั้น Mercurial รู้ว่ามันสามารถละเว้นไฟล์เหล่านั้น
  • สร้างสคริปต์ (ทุบตี) เพื่อเริ่มต้นเซิร์ฟเวอร์ (พร้อม--scriptตัวเลือก) และติดตามเวอร์ชัน
  • การบันทึกสมุดบันทึกจะบันทึก.py-file แต่ไม่ได้เช็คอิน
    • นี่คือข้อเสียเปรียบ : เราสามารถลืมได้
    • มันเป็นคุณสมบัติเช่นกัน: มันเป็นไปได้ที่จะบันทึกสมุดบันทึก (และดำเนินการในภายหลัง) โดยไม่ต้องทำคลัสเตอร์ที่เก็บประวัติ

ความปรารถนา

  • มันจะดีถ้ามีปุ่มสำหรับเช็คอิน / เพิ่ม / ฯลฯ ใน Dashboard ของโน้ตบุ๊ก
  • เช็คเอาท์ไปที่ (ตามตัวอย่าง) file@date+rev.py) ควรเป็นประโยชน์มันจะเป็นการทำงานมากเพื่อเพิ่มที่; และบางทีฉันจะทำเช่นนั้นอีกครั้ง จนถึงตอนนี้ฉันเพิ่งทำด้วยมือ

คุณจะไปจาก.pyไฟล์กลับไปยังสมุดบันทึกได้อย่างไร ฉันชอบวิธีการนี้ แต่เนื่องจาก.ipynb-> .py-> .ipynbอาจสูญเสียฉันจึงไม่ได้พิจารณาเรื่องนี้อย่างจริงจัง
mforbes

นั่นเป็นเรื่องง่าย: โหลดมันโดยยกตัวอย่างโดยวางไว้บน de-Notebook ยกเว้น "ข้อมูลออก" ไม่มีอะไรหายไป
อัลเบิร์ต

ถ้านั่นเป็นเรื่องจริงฉันคิดว่านี่น่าจะใกล้เคียงกับความคิด แต่ดูเหมือนว่าฉันจะจำได้ว่า IPython ไม่ได้มุ่งมั่นที่จะรักษาข้อมูลอย่างสมบูรณ์ในการเปลี่ยนจาก.pyเป็น.ipynbรูปแบบ มีปัญหาเกี่ยวกับเรื่องนี้ - ดังนั้นบางทีนี่อาจเป็นพื้นฐานสำหรับการแก้ปัญหาที่สมบูรณ์
mforbes

ฉันกำลังแปลง.pyไฟล์ไปเป็น.ipynbไฟล์ยาก nbconvertดูเหมือนจะยังไม่รองรับสิ่งนี้และฉันไม่มีแดชบอร์ดของสมุดบันทึกตั้งแต่ฉันทำงานipython notebookด้วยตนเอง คุณมีคำแนะนำทั่วไปเกี่ยวกับวิธีการใช้การแปลงย้อนหลังนี้หรือไม่?
mforbes

แน่นอนว่าการ.pyเปลี่ยนเป็นโน้ตบุ๊กนั้นไม่ได้มีไว้สำหรับการเดินทางไปกลับ ดังนั้นนี่ไม่สามารถแก้ปัญหาทั่วไปได้แม้ว่าจะดีสำหรับคุณ
holdenweb

3

เพื่อติดตามสคริปต์ที่ยอดเยี่ยมโดย Pietro Battiston ถ้าคุณได้รับข้อผิดพลาดในการแยกวิเคราะห์ Unicode ดังนี้:

Traceback (most recent call last):
  File "/Users/kwisatz/bin/ipynb_output_filter.py", line 33, in <module>
write(json_in, sys.stdout, NO_CONVERT)
  File "/Users/kwisatz/anaconda/lib/python2.7/site-packages/IPython/nbformat/__init__.py", line 161, in write
fp.write(s)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2014' in position 11549: ordinal not in range(128)

คุณสามารถเพิ่มที่จุดเริ่มต้นของสคริปต์:

reload(sys)
sys.setdefaultencoding('utf8')

3

ฉันได้สร้างแพ็คเกจไพ ธ อนเพื่อแก้ปัญหานี้

https://github.com/brookisme/gitnb

มันมี CLI ที่มีไวยากรณ์ที่ได้รับแรงบันดาลใจจากคอมไพล์เพื่อติดตาม / อัปเดต / diff notebooks ภายใน git repo ของคุณ

นี่คือตัวอย่าง

# add a notebook to be tracked
gitnb add SomeNotebook.ipynb

# check the changes before commiting
gitnb diff SomeNotebook.ipynb

# commit your changes (to your git repo)
gitnb commit -am "I fixed a bug"

โปรดทราบว่าขั้นตอนสุดท้ายที่ฉันใช้ "gitnb กระทำ" กำลังทำธุรกรรม git ของคุณ มันเป็นเสื้อคลุมสำหรับ

# get the latest changes from your python notebooks
gitnb update

# commit your changes ** this time with the native git commit **
git commit -am "I fixed a bug"

มีวิธีการอีกหลายวิธีและสามารถกำหนดค่าเพื่อให้ต้องการอินพุตผู้ใช้มากขึ้นหรือน้อยลงในแต่ละขั้นตอน แต่นั่นเป็นแนวคิดทั่วไป


3

หลังจากขุดรอบในที่สุดผมก็พบว่าก่อนการบันทึกเบ็ดนี้ค่อนข้างง่ายในเอกสาร Jupyter มันแถบข้อมูลเซลล์เอาท์พุท คุณต้องวางลงในjupyter_notebook_config.pyไฟล์ (ดูคำแนะนำด้านล่าง)

def scrub_output_pre_save(model, **kwargs):
    """scrub output before saving notebooks"""
    # only run on notebooks
    if model['type'] != 'notebook':
        return
    # only run on nbformat v4
    if model['content']['nbformat'] != 4:
        return

    for cell in model['content']['cells']:
        if cell['cell_type'] != 'code':
            continue
        cell['outputs'] = []
        cell['execution_count'] = None
        # Added by binaryfunt:
        if 'collapsed' in cell['metadata']:
            cell['metadata'].pop('collapsed', 0)

c.FileContentsManager.pre_save_hook = scrub_output_pre_save

จากคำตอบของ Rich Signell :

หากคุณไม่แน่ใจว่าในการที่จะหาไดเรกทอรีของjupyter_notebook_config.pyแฟ้มที่คุณสามารถพิมพ์jupyter --config-dir[เข้าพร้อมรับคำสั่ง / ขั้ว] jupyter notebook --generate-configและถ้าคุณไม่พบแฟ้มที่มีคุณสามารถสร้างได้โดยการพิมพ์


1
ฉันจะทราบว่าวิธีนี้จะไม่บันทึกผลลัพธ์ใด ๆลงในดิสก์และค่อนข้างอิสระจากปัญหาการควบคุมเวอร์ชัน
bdforbes

2

ฉันทำในสิ่งที่ Albert & Rich ทำ - อย่าใช้ไฟล์. ipynb เวอร์ชัน (เนื่องจากไฟล์เหล่านี้อาจมีภาพซึ่งทำให้เกิดความยุ่งเหยิง) แต่ให้เรียกใช้ipython notebook --scriptหรือใส่c.FileNotebookManager.save_script = Trueในไฟล์กำหนดค่าของคุณเสมอเพื่อให้ไฟล์ (เวอร์ชัน) .pyสามารถสร้างได้ตลอดเวลาเมื่อคุณบันทึกสมุดบันทึกของคุณ

ในการสร้างสมุดบันทึกใหม่ (หลังจากตรวจสอบ repo หรือเปลี่ยนสาขา) ฉันวางสคริปต์py_file_to_notebooks.pyไว้ในไดเรกทอรีที่ฉันเก็บสมุดบันทึกของฉัน

ตอนนี้หลังจากตรวจสอบ repo เพียงแค่เรียกใช้python py_file_to_notebooks.pyเพื่อสร้างไฟล์ ipynb หลังจากสลับสาขาคุณอาจต้องเรียกใช้python py_file_to_notebooks.py -ovเพื่อเขียนทับไฟล์ ipynb ที่มีอยู่

เพียงเพื่อความปลอดภัยก็เป็นการดีที่จะเพิ่ม ไฟล์*.ipynbของคุณ.gitignore

แก้ไข: ฉันไม่ทำเช่นนี้อีกเพราะ (A) คุณต้องสร้างสมุดบันทึกของคุณใหม่จากไฟล์ py ทุกครั้งที่คุณชำระเงินที่สาขาและ (B) มีสิ่งอื่นเช่น markdown ในสมุดบันทึกที่คุณสูญเสีย ฉันแทนการเอาท์พุทจากโน้ตบุ๊กโดยใช้ตัวกรอง git คำอธิบายเกี่ยวกับวิธีการทำเช่นนี้คือที่นี่


ฉันชอบความคิดนี้ แต่หลังจากการทดสอบพบว่าการแปลงจาก.pyไฟล์กลับ.ipynbเป็นปัญหาโดยเฉพาะกับโน้ตบุ๊กรุ่น 4 ที่ยังไม่มีตัวแปลง ปัจจุบันเราต้องใช้ผู้นำเข้า v3 จากนั้นเปลี่ยนเป็น v4 และฉันกังวลเล็กน้อยเกี่ยวกับการเดินทางที่ซับซ้อนนี้ นอกจากนี้.pyไฟล์ไม่ได้เป็นตัวเลือกที่ดีถ้าโน้ตบุ๊คเป็นรหัสจูเลียเป็นหลัก! ในที่สุด--scriptก็เลิกใช้แล้วดังนั้นฉันคิดว่า hooks เป็นวิธีที่จะไป
mforbes

โซลูชันตัวกรอง git ในลิงค์ของคุณนั้นดีคุณควรคัดลอกคำตอบของคุณจากที่นี่ :-)
mcarans

2

ตกลงดังนั้นดูเหมือนว่าทางออกที่ดีที่สุดในปัจจุบันตามการสนทนาที่นี่คือการสร้างตัวกรอง git เพื่อเอาท์พุทโดยอัตโนมัติจากไฟล์ ipynb เมื่อกระทำ

นี่คือสิ่งที่ฉันทำเพื่อให้มันทำงานได้ (คัดลอกมาจากการสนทนา):

ฉันแก้ไขไฟล์ nbstripout ของ cfriedline เล็กน้อยเพื่อให้ข้อผิดพลาดที่ให้ข้อมูลเมื่อคุณไม่สามารถนำเข้า IPython ล่าสุดได้: https://github.com/petered/plato/blob/fb2f4e252f50c79768920d0e47b870a8d799e92b/notebooks/config/strip_noteoutputเพื่อให้ repout ของฉัน พูดมา./relative/path/to/strip_notebook_output

เพิ่มไฟล์. gitattributes ไปยังรูทของ repo ด้วย:

*.ipynb filter=stripoutput

และสร้างสิ่งsetup_git_filters.shที่บรรจุ

git config filter.stripoutput.clean "$(git rev-parse --show-toplevel)/relative/path/to/strip_notebook_output" 
git config filter.stripoutput.smudge cat
git config filter.stripoutput.required true

และวิ่งsource setup_git_filters.shได้ สิ่ง $ แฟนซี (git rev-parse ... ) คือการหาเส้นทางท้องถิ่นของ repo ของคุณบนเครื่องใด ๆ (Unix)


1

ส่วนขยาย jupyter นี้ช่วยให้ผู้ใช้สามารถผลักดันสมุดบันทึก jupyter โดยตรงไปยัง github

โปรดดูที่นี่

https://github.com/sat28/githubcommit


คุณช่วยอธิบายสิ่งนี้ได้ไหม? การกระจายไม่ชัดเจนโดยเฉพาะอย่างยิ่ง
อเล็กซ์ Monras

@AlexMonras วิธีนี้จะเพิ่มปุ่มในสมุดบันทึก jupyter โดยตรงจากที่คุณสามารถผลักดันสมุดบันทึกไปยัง repo GitHub ของคุณด้วยข้อความคอมมิชชัน
sat

1

นี่คือเดือนเมษายน 2020 และมีกลยุทธ์และเครื่องมือมากมายสำหรับการควบคุมเวอร์ชันโน๊ตบุ๊ค Jupyter นี่คือภาพรวมคร่าวๆของเครื่องมือทั้งหมดที่คุณสามารถใช้ได้

  • nbdime - ดีสำหรับการกระจายและการรวมโน้ตบุ๊กในพื้นที่

  • nbstripout - ตัวกรอง git เพื่อลบเอาต์พุตโน้ตบุ๊กโดยอัตโนมัติก่อนที่จะส่งมอบแต่ละครั้ง

  • jupytext - เก็บไฟล์สหาย. py ซิงค์กับสมุดบันทึกแต่ละรายการ คุณยอมรับไฟล์. py เท่านั้น

  • nbconvert - แปลงสมุดบันทึกเป็นสคริปต์ไพ ธ อนหรือ HTML (หรือทั้งสองอย่าง) และคอมมิทไฟล์ประเภทอื่น

  • ReviewNB - แสดงความแตกต่างของโน้ตบุ๊ก (พร้อมกับเอาต์พุต) สำหรับการส่งคำขอหรือดึงบน GitHub ท่านสามารถเขียนความคิดเห็นในเซลล์โน้ตบุ๊คเพื่อหารือเกี่ยวกับการเปลี่ยนแปลง (ภาพหน้าจอด้านล่าง)

ป้อนคำอธิบายรูปภาพที่นี่

คำเตือน: ฉันสร้าง ReviewNB


0

วิธีการเกี่ยวกับความคิดที่กล่าวถึงในโพสต์ด้านล่างซึ่งควรเก็บรักษาเอาท์พุทของสมุดบันทึกไว้ด้วยการโต้แย้งว่าอาจต้องใช้เวลานานในการสร้างและเป็นประโยชน์เนื่องจาก GitHub สามารถสร้างสมุดบันทึกได้ มีตะขอบันทึกอัตโนมัติที่เพิ่มเข้ามาสำหรับการส่งออกไฟล์. py ใช้สำหรับ diffs และ. html เพื่อแบ่งปันกับสมาชิกในทีมที่ไม่ได้ใช้โน้ตบุ๊กหรือคอมไพล์

https://towardsdatascience.com/version-control-for-jupyter-notebook-3e6cef13392d

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.