IPython not defterlerini sürüm kontrolü altında kullanma


569

IPython dizüstü bilgisayarları sürüm kontrolü altında tutmak için iyi bir strateji nedir ?

Dizüstü bilgisayar biçimi sürüm kontrolü için oldukça uygundur: dizüstü bilgisayar ve çıkışları sürüm kontrol etmek istiyorsanız, bu oldukça iyi çalışır. Rahatsızlık, özellikle filmler ve parseller için büyük ikili lekeler olabilen hücre çıktıları (aka. "Yapı ürünleri") hariç olmak üzere, yalnızca girdinin sürüm kontrolünü yapmak istediğinde ortaya çıkar. Özellikle, ben iyi bir iş akışı bulmaya çalışıyorum:

  • çıktıyı dahil etmek veya hariç tutmak arasında seçim yapmamı sağlar,
  • istemediğimde yanlışlıkla çıkış yapmama engel oluyor,
  • yerel sürümümde çıktı tutmama izin veriyor,
  • Sürüm kontrol sistemimi kullanarak girişlerde değişiklik olduğunda ne zaman görmemi sağlıyor (yani yalnızca sürümleri girişleri kontrol ediyor, ancak yerel dosyamda çıktılar varsa, girişlerin değişip değişmediğini görmek için (bir taahhüt gerektiren) Sürüm denetimi durum komutunu kullanmak, yerel dosyanın çıktıları olduğundan her zaman bir fark kaydeder.)
  • çalışma defterimi (çıktıyı içeren) güncellenmiş temiz bir defterden güncellememe izin veriyor. (Güncelleme)

Belirtildiği gibi, çıkışları dahil etmeyi seçtiğimde ( örneğin nbviewer kullanılırken istenir ), o zaman her şey yolunda. Ben ne zaman sorunudur yok çıkış sürüm kontrolü istiyorum. Dizüstü bilgisayarın çıktısını çıkarmak için bazı araçlar ve komut dosyaları vardır, ancak sıklıkla aşağıdaki sorunlarla karşılaşıyorum:

  1. Çıktının yanlışlıkla bir versiyonunu işlerim, böylece depomu kirletirim.
  2. Sürüm denetimini kullanmak için çıktıyı temizlerim, ancak çıktıyı yerel kopyamda tutmayı tercih ederim (bazen örneğin çoğaltmak biraz zaman alabilir).
  3. Çıkışı şeritleyen bazı komut dosyaları formatı Cell/All Output/Clearmenü seçeneğine göre biraz değiştirir , böylece farklarda istenmeyen gürültü oluşturur. Bu, bazı cevaplar tarafından çözülür.
  4. Değişiklikleri dosyanın temiz bir sürümüne çekerken, bu değişiklikleri her şeyi yeniden çalıştırmak zorunda kalmadan çalışma not defterime dahil etmenin bir yolunu bulmam gerekiyor. (Güncelleme)

Aşağıda tartışacağım birkaç seçenek ele aldım, ancak henüz iyi ve kapsamlı bir çözüm bulamadım. Tam bir çözüm IPython'da bazı değişiklikler gerektirebilir veya bazı basit harici komut dosyalarına güvenebilir. Şu anda mercurial kullanıyorum , ama git ile çalışan bir çözüm istiyorum : ideal bir kontrol sürüm kontrolü agnostik olurdu.

Bu sorun birçok kez tartışılmıştır, ancak kullanıcının bakış açısından kesin veya açık bir çözüm yoktur. Bu sorunun cevabı kesin bir strateji sağlamalıdır. IPython'un yakın zamanda (hatta geliştirme) bir sürümünü veya kolayca yüklenen bir uzantıyı gerektiriyorsa sorun yoktur.

Güncelleme: Gregory Crosswhite'ın önerilerini kullanarak isteğe bağlı olarak her kaydetmeyle birlikte bir sürüm kaydeden değiştirilmiş dizüstü bilgisayar sürümümle oynuyorum . Bu, kısıtlamalarımın çoğunu karşılar, ancak aşağıdakileri çözülmez:.clean

  1. Bu henüz standart bir çözüm değildir (ipython kaynağının değiştirilmesini gerektirir. Bu davranışı basit bir uzantı ile gerçekleştirmenin bir yolu var mı?
  2. Geçerli iş akışı ile ilgili bir sorunum değişiklikleri çekmek. Bunlar .cleandosyaya gelecek ve daha sonra bir şekilde çalışma sürümüme entegre edilmesi gerekiyor. (Tabii ki, her zaman dizüstü bilgisayarı yeniden yürütebilirim, ancak bu bir acı olabilir, özellikle de sonuçların bazıları uzun hesaplamalara, paralel hesaplamalara vb. Bağlıysa). . Belki de ipycache gibi bir uzantı içeren bir iş akışı işe yarayabilir, ancak bu biraz karmaşık görünüyor.

notlar

Çıktıyı Çıkarma (Sıyırma)

  • Dizüstü bilgisayar çalışırken, Cell/All Output/Clearçıktıyı kaldırmak için menü seçeneği kullanılabilir .
  • Çıktıyı kaldırmak için, çıktıyı kaldıran ancak dizüstü bilgisayar arabirimini kullanmakla aynı çıktıyı üretmeyen nbstripout.py komut dosyası gibi bazı komut dosyaları vardır . Bu, sonunda ipython / nbconvert deposuna dahil edildi , ancak bu değişikliklerin şimdi ipython / ipython'a dahil edildiğini belirten kapatıldı , ancak karşılık gelen işlevsellik henüz dahil edilmemiş gibi görünüyor. (güncelleme) Bu varlık dedi Gregory Crosswhite çözümü bu, hatta yürütmesini olmadan oldukça kolay yapmak olduğunu gösterir ipython / nbconvert, bu yüzden düzgün bir şekilde takılabilirse bu yaklaşım muhtemelen uygulanabilir. (Ancak, her sürüm kontrol sistemine eklemek iyi bir fikir gibi görünmüyor - bu bir şekilde dizüstü bilgisayar mekanizmasına takılmalıdır.)

Haber Grupları

Sorunlar

Çekme İstekleri


Github.com/ipython/ipython'da sorun olarak eklemek veya bu hedefi ilerletmenize yardımcı olacak bir çekme isteği göndermek harika bir şey gibi görünüyor .
Kyle Kelley

4
Çıktıyı kaldırmak için çalışan bir komut dosyanız varsa, işlem yapmadan önce otomatik olarak uygulamak için Git "temiz" filtresini kullanabilirsiniz (bkz. Temizleme / bulaşma filtreleri).
Matthias

1
@foobarbecue Soru tatmin edici olmayan geçici çözümler içeriyor: her birinde en az bir sınırlama var. Şimdi PR 4175 birleştirildiğine göre, tam bir çözüm muhtemelen formüle edilebilir, ancak yine de yapılması gerekir. Biraz zamanım olur olmaz, başka biri de tatmin edici bir çözüm sunmazsa (bir cevap olarak) yapacağım.
mforbes

1
@saroele Henüz önerilen bir çözüm bulamadım: --scriptSeçenekle devam edecektim , ancak bu kaldırıldı. Post-save kancalar uygulanana kadar bekliyorum ( planlanan ), bu noktada birkaç tekniği birleştirerek kabul edilebilir bir çözüm sağlayabileceğimi düşünüyorum.
mforbes

1
@mforbes Görünüşe göre PR yorumunuzdan birkaç gün sonra birleştirildi. Siz veya benden daha bilgili biri, yeni özelliğin nasıl kullanılacağını gösteren bir yanıt gönderebilir mi?
KobeJohn

Yanıtlar:


124

İşte git ile çözümüm. Her zamanki gibi eklemenizi ve taahhüt etmenizi (ve fark etmenizi) sağlar: bu işlemler çalışma ağacınızı değiştirmez ve aynı zamanda bir dizüstü bilgisayarı (yeniden) çalıştırmak git geçmişinizi değiştirmez.

Bu muhtemelen diğer VCS'lere uyarlanabilse de, gereksinimlerinizi karşılamadığını biliyorum (en azından VSC agnostisitesi). Yine de, benim için mükemmel ve özellikle parlak bir şey olmasa da ve birçok insan muhtemelen zaten kullanıyor olsa da, etrafta dolaşarak nasıl uygulanacağı hakkında net talimatlar bulamadım. Bu yüzden diğer insanlar için yararlı olabilir.

  1. Bu içeriğe sahip bir dosyayı bir yere kaydedin (aşağıdakiler için varsayalım ~/bin/ipynb_output_filter.py)
  2. Yürütülebilir yap ( chmod +x ~/bin/ipynb_output_filter.py)
  3. ~/.gitattributesAşağıdaki içerikle dosyayı oluşturun

    *.ipynb    filter=dropoutput_ipynb
    
  4. Aşağıdaki komutları çalıştırın:

    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
    

Bitti!

Sınırlamalar:

  • sadece git ile çalışır
  • git, daldaysanız somebranchve yaparsanız git checkout otherbranch; git checkout somebranch, genellikle çalışma ağacının değişmesini beklersiniz. Burada bunun yerine, kaynağı iki dal arasında farklılık gösteren not defterlerinin çıktı ve hücre numaralarını kaybedmiş olacaksınız.
  • daha genel olarak, Gregory'nin çözümünde olduğu gibi, çıktı hiç versiyonlanmamıştır. Bir ödeme içeren her şeyi her yaptığınızda atmak için yaklaşım, ayrı dosyalarda saklanarak değiştirilebilir (ancak yukarıdaki kodun çalıştırıldığı zaman, taahhüt kimliğinin bilinmediğini unutmayın!), ve muhtemelen bunları versiyonlamak (ancak git commit notebook_file.ipynben azından git diff notebook_file.ipynbbase64 çöpünden uzak kalmasına rağmen, bunun a'dan daha fazla bir şey gerektireceğini unutmayın ).
  • Bu arada, bazı çıktılar içeren bir kod çekerseniz (yani bu yaklaşımı kullanmayan bir kişi tarafından taahhüt edilirse), çıkış normal olarak kontrol edilir. Yalnızca yerel olarak üretilen çıktılar kaybedilir.

Çıkışını içeren yapıyor birleştirmeleri neredeyse çıkışını geçersiz kılmak için garanti edildiğini haber - My çözüm şahsen oluşturulan şeyler sürüm bilgisi tutmak için değil sevmiyorum gerçeğini yansıtır ya üretkenliğinizi veya her ikisi.

DÜZENLE:

  • Eğer önerdiğim gibi çözümü benimserseniz - yani, küresel olarak - sürüm çıktısını almak istediğiniz bazı git repo için sorun yaşayacaksınız . Dolayısıyla, belirli bir git deposu için çıkış filtresini devre dışı bırakmak istiyorsanız , içinde bir dosya .git / info / attributes oluşturun

    **. ipynb filtresi =

içerik olarak. Açıkçası, aynı şekilde tam tersini yapmak mümkündür: filtrelemeyi yalnızca belirli bir depo için etkinleştirin .

  • kod artık kendi git deposunda saklanıyor

  • yukarıdaki talimatlar ImportErrors ile sonuçlanıyorsa, komut dosyasının yolundan önce "ipython" eklemeyi deneyin:

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

EDIT : Mayıs 2016 (Şubat 2017'de güncellendi): Senaryom için birkaç alternatif var - tamlık için, tanıdığımların bir listesi: nbstripout ( diğer varyantlar ), nbstrip , jq .


2
Çektiğiniz değişiklikleri birleştirme konusuyla nasıl başa çıkıyorsunuz? Tüm çıktıyı yeniden oluşturmak zorunda kalıyor musunuz? (Sanırım bu ikinci sınırlamanızın bir tezahürü.)
mforbes

1
@zhermes: bu genişletilmiş sürüm iyi olmalı
Pietro Battiston

1
Bu git filtreleri yöntemini harici bir fark aracıyla kullanmanın bir yolu var mı? Filtre, normal komut satırı aracını kullanırsam uygulanır ancak meld'i fark aracı olarak kullanıyorsam uygulanmaz. stackoverflow.com/q/30329615/578770
FA

1
ImportErrorBaşlamasını önlemek için ipython kullanarak çalıştırmak için yukarıdaki değiştirmek zorunda kaldı:git config --global filter.dropoutput_ipynb.clean ipython ~/bin/ipynb_output_filter.py
chris838

1
Awsome çözüm Pietro, teşekkürler :) Benim durumumda senaryoyu kullanırken 2 şeyi değiştirdim: 1) Ben aksine reponun kök .gitattributes filtre tercih ettim ~/.gitattributes, st diğer insanlar benimle aynı filtreleri var 2 ) workdir/**/*.ipynb filter=dropoutput_ipynbNormal ifadeyi tanımladım ve not defterlerimin çoğunu workdir / => içine koyuyorum.
Svend

63

Ürünün Jupyter Notebooks olduğu bir işbirliği projemiz var ve son altı aydır harika çalışan bir yaklaşım kullanıyoruz: .pydosyaları otomatik olarak kaydetmeyi etkinleştiriyoruz ve hem .ipynbdosyaları hem de dosyaları izliyoruz .py.

Bu şekilde birisi en son not defterini görüntülemek / indirmek isterse bunu github veya nbviewer aracılığıyla yapabilir ve birisi not defteri kodunun nasıl değiştiğini görmek isterse, .pydosyalardaki değişikliklere bakabilir .

İçin Jupyterdizüstü sunucularında , bu satırları ekleyerek yapılabilir

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

için jupyter_notebook_config.pydosya ve dizüstü sunucuyu yeniden başlatmadan.

jupyter_notebook_config.pyDosyanızı hangi dizinde bulacağınızdan emin değilseniz, yazabilirsiniz jupyter --config-dirve dosyayı orada bulamazsanız, yazarak oluşturabilirsiniz jupyter notebook --generate-config.

İçin Ipython 3dizüstü sunucularında , bu satırları ekleyerek yapılabilir

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

için ipython_notebook_config.pydosya ve dizüstü sunucuyu yeniden başlatmadan. Bu satırlar cevap @minrk sağlanan bir github sorunları ve @dror SO yanıta da dahil eder.

İçin Ipython 2dizüstü sunucularında , bu kullanarak sunucuyu başlatarak yapılabilir:

ipython notebook --script

veya satırı ekleyerek

c.FileNotebookManager.save_script = True

için ipython_notebook_config.pydosya ve dizüstü sunucuyu yeniden başlatmadan.

ipython_notebook_config.pyDosyanızı hangi dizinde bulacağınızdan emin değilseniz, yazabilirsiniz ipython locate profile defaultve dosyayı orada bulamazsanız, yazarak oluşturabilirsiniz ipython profile create.

İşte bu yaklaşımı kullanan github projemiz : ve bir not defterinde son değişiklikleri araştırmanın github örneği .

Bundan çok memnunuz.


1
Kullanımın --scriptpratikte işe yaradığına dair ek kanıt için teşekkür ederiz . Buradaki sorun, görüntüler saklanırsa gerçek not defterlerinin çok büyük olması olabilir. Bu yol boyunca ideal bir çözüm , sadece en son dolu dizüstü bilgisayarı takip etmek için git-ekx gibi bir şey kullanabilir .
mforbes

Ipython 3.x sürümünde --scriptkullanımdan kaldırılmıştır. ipython.org/ipython-doc/3/whatsnew/version3.html
Dror

Teşekkürler @dror, burada da sağladığınız gibi minrk'in ipython 3.x çözümünü sağlamak için cevabımı güncelledim.
Zengin Signell

10
Güncelleme: Bu çözüm, iPython'dan Jupyter'in "Büyük Bölünmesi" nedeniyle iPython sürüm 4'te bozulmuştur. Bu çözümü sürüm 4'e ayarlamak için, jupyter notebook --generate-configbir yapılandırma dosyası oluşturma komutunu kullanın. Komut jupyter --config-dir, hangi dizinin yapılandırma dosyalarını içerdiğini bulur. Ve @Rich tarafından verilen kod snippet'i adlı dosyaya eklenmelidir jupyter_notebook_config.py. Gerisi eskisi gibi çalışıyor.
mobius günberi

2
@Mobiusdumpling tarafından noktaya ek olarak, yerine check_call(['ipython'ile check_call(['jupyter'aksi takdirde bir uyarı alacak, ipython nbconvertkullanımdan kaldırıldı ve kullanmak gerekir jupyter nbconvertbunun yerine. (Jupyter v4.1.0, iPython v4.1.2)
cutculus

36

Hem Git'i hem de Mercurial'ı destekleyen MinRKs gistlerinenbstripout dayanarak oluşturdum (mforbes sayesinde). Komut satırında bağımsız olarak veya / aracılığıyla mevcut depoya kolayca (un) kurulabilen bir filtre olarak kullanılması amaçlanmıştır .nbstripout installnbstripout uninstall

PyPI'den alın veya basitçe

pip install nbstripout

Yukarıda açıklanan kaydetme sonrası kancaları kullanarak otomatik olarak oluşturulan .ipynb ve karşılık gelen .py tutmak bir iş akışı düşünüyorum. Ben diffs için .py kullanmak istiyorum - nbstripout .py dosyasını hücre yürütme sayaçlarından (# [[]] In [*] olarak değiştirildi) temizleyebilsin, böylece diffs dağınık olmamalı mı yoksa bunu yapmak için basit bir komut dosyası oluşturmak?
Krzysztof Słowiński

1
@ KrzysztofSłowiński Hayır, nbstripoutDizüstü Bilgisayarın JSON formatına bağlı olduğu için bu kullanım durumunu kolayca desteklemez. Kullanım durumunuza özel bir komut dosyası yazmanız daha iyi olur.
kynan


13

Dizüstü bilgisayarlardaki birkaç yıl çıkardıktan sonra daha iyi bir çözüm bulmaya çalıştım. Şimdi tasarladığım Jupyter Notebook ve Jupyter Lab için bir uzantı olan Jupytext kullanıyorum.

Jupytext, Jupyter not defterlerini çeşitli metin biçimlerine (Scripts, Markdown ve R Markdown) dönüştürebilir. Ve tersine. Ayrıca bir not defterini bu biçimlerden biriyle eşleştirme ve not defterinin iki temsilini (bir .ipynbve bir .md/.py/.Rdosya) otomatik olarak senkronize etme seçeneği sunar .

Jupytext'in yukarıdaki soruları nasıl yanıtladığını açıklayayım:

çıktıyı dahil etmek veya hariç tutmak arasında seçim yapmamı sağlar,

.md/.py/.RDosya yalnızca giriş hücrelerini içerir. Bu dosyayı daima izlemelisiniz. Sürüm .ipynbEğer çıkışları izlemek istediğiniz takdirde dosya.

istemediğimde yanlışlıkla çıkış yapmama engel oluyor,

ekle *.ipynbiçin.gitignore

yerel sürümümde çıktı tutmama izin veriyor,

Çıktılar (yerel) .ipynbdosyada korunur

Sürüm kontrol sistemimi kullanarak girişlerde değişiklik olduğunda ne zaman görmemi sağlıyor (yani yalnızca sürümleri girişleri kontrol ediyor, ancak yerel dosyamda çıktılar varsa, girişlerin değişip değişmediğini görmek için (bir taahhüt gerektiren) Sürüm denetimi durum komutunu kullanmak, yerel dosyanın çıktıları olduğundan her zaman bir fark kaydeder.)

.py/.RVeya .mddosyadaki fark aradığınız şeydir

çalışma defterimi (çıktıyı içeren) güncellenmiş temiz bir defterden güncellememe izin veriyor. (Güncelleme)

.py/.RVeya .mddosyasının en son sürümünü alın ve not defterinizi Jupyter'de (Ctrl + R) yenileyin. Dosyadan eşleşen çıktılarla metin dosyasından en son girdi hücrelerini alırsınız .ipynb. Çekirdek etkilenmez, yani yerel değişkenleriniz korunur - bıraktığınız yerde çalışmaya devam edebilirsiniz.

Jupytext ile sevdiğim şey, dizüstü bilgisayarın (bir .py/.Rveya .mddosya biçiminde ) en sevdiğiniz IDE'de düzenlenebilmesidir. Bu yaklaşımla, bir dizüstü bilgisayarı yeniden düzenlemek kolaylaşır. İşiniz bittiğinde, Jupyter'de not defterini yenilemeniz yeterlidir.

Denemek istiyorsanız: Jupytext'i yükleyin pip install jupytextve Jupyter Notebook veya Lab editörünüzü yeniden başlatın. Sürüm kontrolü istediğiniz dizüstü açın ve eşleştirmeniz kullanarak bir Markdown dosyası (veya bir komut dosyası) için Jupytext Menüsü Jupyter defterindeki (veya Jupytext komutları Jupyter Laboratuarı'nda). Dizüstü bilgisayarınızı kaydedin ve iki dosyayı elde edin: orijinal .ipynb, ayrıca dizüstü bilgisayarın vaat edilen metin temsili, sürüm kontrolü için mükemmel bir seçimdir!

İlgilenenler için: Jupytext komut satırında da mevcuttur .


13

Güncelleştirme : Artık Jupyter Notebook dosyalarını doğrudan Visual Studio Code'da düzenleyebilirsiniz . Not defterini veya dönüştürülen python dosyasını düzenlemeyi seçebilirsiniz.

Sonunda Jupyter ve Git'in birlikte güzel oynaması için verimli ve basit bir yol buldum. Hala ilk adımlardayım, ama zaten diğer kıvrımlı çözümlerden çok daha iyi olduğunu düşünüyorum.

Visual Studio Code , Microsoft'un serin ve açık kaynak kod düzenleyicisidir. Jupyter Notebook'u python kodu olarak içe aktarmanıza izin veren mükemmel bir Python uzantısına sahiptir . Artık Jupyter Notebook'ları doğrudan düzenleyebilirsiniz .

Not defterinizi bir python dosyasına aktardıktan sonra, tüm kod ve işaretleme, yorumlarda özel işaretçilerle sıradan bir python dosyasında birlikte olacaktır. Aşağıdaki resimde görebilirsiniz:

Python'a dönüştürülmüş bir dizüstü bilgisayar ile VSCode editörü

Python dosyanız sadece defter giriş hücrelerinin içeriğine sahiptir. Çıktı bölünmüş bir pencerede oluşturulacaktır. Not defterinde saf kod var, sadece yürütürken değişmez. Kodunuzla karıştırılmış çıktı yok. Farklarınızı analiz etmek için garip JSON anlaşılmaz formatı yok.

Sadece her fark fark kolayca saf python kodu.

.ipynbArtık dosyalarımı sürümlendirmem bile gerekmiyor . Bir *.ipynbçizgi koyabilirim .gitignore.

Birini yayınlamak veya onunla paylaşmak için bir not defteri mi oluşturmanız gerekiyor? Sorun değil, etkileşimli python penceresindeki dışa aktar düğmesini tıklayın

Bir python dosyasını Not Defteri biçimine dışa aktarma

Dizüstü bilgisayarı doğrudan düzenliyorsanız, artık bir simge var Convert and save to a python script. Visual Studio Code Jupyter simgeleri

İşte Visual Studio Code içindeki bir not defterinin ekran görüntüsü:

Not Defteri'ni VSCode içinde düzenleme

Sadece bir gündür kullanıyorum, ama sonunda Jupyter'ı Git ile mutlu bir şekilde kullanabilirim.

PS: VSCode kod tamamlama Jupyter çok daha iyi.


12

(2017-02)

stratejiler

  • on_commit ():
    • çıktıyı sıyırın> name.ipynb ( nbstripout,)
    • çıktıyı sıyırın> name.clean.ipynb ( nbstripout,)
    • her zaman nbconvertpython'a: name.ipynb.py ( nbconvert)
    • her zaman işaretlemeye dönüştür: name.ipynb.md ( nbconvert, ipymd)
  • vcs.configure ():
    • git difftool, mergetool: nbdime'den nbdiff ve nbmerge

araçlar


11

Yukarıdaki en popüler 2016 cevapları, 2019'da bunu yapmanın daha iyi yoluna kıyasla tutarsız hack'lerdir.

Birkaç seçenek var, soruyu cevaplayan en iyi şey Jupytext.

Jupytext

Yakalamak Jupytext Veri Bilimi Doğru makaleye

Sürüm denetimi ile çalışma şekli, .py ve .ipynb dosyalarını sürüm denetimine koymanızdır. Girişin farklı olmasını istiyorsanız .py'ye, en son oluşturulan çıktıyı istiyorsanız .ipynb'ye bakın.

Dikkate değer sözler: VS studio, nbconvert, nbdime, hidrojen

Biraz daha fazla çalışmayla, VS stüdyosu ve / veya hidrojen (veya benzeri) bu iş akışının çözümünde baskın oyuncular olacak.


9

Sadece mükemmel bir çözüm gibi görünüyor "jupytext" rastlamak. Not defterinden bir .py dosyası oluşturur ve her ikisini de senkronize tutar. Çıktıları kaybetmeden .py dosyası aracılığıyla girişleri kontrol edebilir, farklılaştırabilir ve birleştirebilirsiniz. Not defterini açtığınızda, giriş hücreleri için .py ve çıkış için .ipynb kullanır. Çıkışı git'e dahil etmek istiyorsanız ipynb'yi ekleyebilirsiniz.

https://github.com/mwouts/jupytext


9

Dizüstü bilgisayarlar için sürüm kontrolünü ele alacak çok fazla strateji ve araç olduğundan, uygun bir strateji seçmek için bir akış şeması oluşturmaya çalıştım (Nisan 2019'da oluşturuldu)

Sürüm kontrol stratejisini seçmek için karar akışı


8

Belirtildiği gibi --script, kullanımdan kaldırılmıştır 3.x. Bu yaklaşım bir kaydetme sonrası kancası uygulanarak kullanılabilir. Özellikle aşağıdakileri ekleyin 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

Kod # 8009'dan alınmıştır .


Kaydetme sonrası kanca kullanımını gösterdiğin için teşekkürler. Ne yazık ki, belirtildiği gibi, .pydosyadan bir not defterine geri dönmek sorunludur, bu yüzden bu maalesef tam bir çözüm değildir. (Ben .pydefter yerine dosyaları diff çok güzel olduğu gibi isterdim . Belki de yeni notebook diff özelliği yararlı olacaktır.
mforbes

1
Teşekkürler! Şimdi bu hile --script, sürüm kontrolü ne olursa olsun , davranışı yeniden oluşturmak için kullanıyorum . İlk başta bazı problemlerim vardı, bu yüzden birini biraz zaman kurtarabilirsem: 1) ipython_notebook_config.pyProfil klasöründe eksikse, ipython profile createoluşturmak için çalıştırın . 2) Kaydetme sonrası çağanoz yoksayılmış gibi görünüyorsa --debug, sorunu teşhis etmek için ipython'u çalıştırın . 3) komut hatası ile başarısız olursa ImportError: No module named mistune- basit minstue yükleyin: pip install mistune.
Joe

7

Ne yazık ki, Mercurial hakkında çok şey bilmiyorum, ancak Git komutlarımı Mercurial eşdeğerlerine çevirebilmeniz umuduyla size Git ile çalışan olası bir çözüm verebilirim.

Arka plan için Git'te addkomut, bir dosyada yapılan değişiklikleri bir hazırlama alanına depolar. Bunu yaptıktan sonra, dosyada daha sonra yapılan değişiklikler Git dosyasında da sahne almasını söylemediğiniz sürece yoksayılır. Dolayısıyla, verilen dosyaların her biri için, her dışarı şeritler, aşağıdaki komut dosyası, outputsve prompt_number sections, soyulmuş dosyayı aşamalarında ve orijinali geri yükler:

NOT: Bunu çalıştırmak size benzer bir hata mesajı alırsa ImportError: No module named IPython.nbformat, ipythonbunun yerine komut dosyasını çalıştırmak için kullanın python.

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)

Komut dosyası, değişikliklerini yapmak istediğiniz dosyalarda çalıştırıldıktan sonra çalıştırın git commit.


Önerin için teşekkürler. Mercurial'ın git gibi bir hazırlama alanı yoktur (ancak bu amaçla cıva kuyrukları kullanılabilir ). Bu arada, temiz bir sürümü .cleanuzantısı olan bir kaydetme kancasına bu kodu eklemeyi denedim . Ne yazık ki, IPython'u doğrudan değiştirmeden bunu nasıl yapacağımı göremedim (bu değişiklik oldukça önemsiz olmasına rağmen). Bir süre bununla oynayacağım ve tüm ihtiyaçlarıma uygun olup olmadığını göreceğim.
mforbes

6

Çok pragmatik bir yaklaşım kullanıyorum; çeşitli dizüstü bilgisayarlar için iyi çalışır. Hatta not defterlerini 'aktarmam' bile mümkün. Hem Windows için Unix / MacOS olarak çalışır.
Al basit olduğunu, yukarıdaki sorunları çözmek olduğunu düşündüm ...

kavram

Temel olarak, do not izlemek .ipnyb-dosyalar, sadece karşılık gelen .py-dosyalar. Dizüstü bilgisayar sunucusunu bu seçenekle
başlatarak, dizüstü bilgisayar--script kaydedildiğinde bu dosya otomatik olarak oluşturulur / kaydedilir.

Bu .pydosyalar tüm girdileri içerir; kod olmayan, hücre kenarlıkları gibi yorumlara kaydedilir. Bu dosya, bir not defteri (yeniden) oluşturmak için not defteri sunucusuna okunabilir / aktarılabilir (ve sürüklenebilir). Sadece çıktı gitti; tekrar çalıştırılıncaya kadar.

Şahsen ben dosyaları sürüm-takip için cıva kullanın .py; ekleyin ve eklemek için normal (komut satırı) komutlarını kullanın, giriş yapın (vb.). Diğer birçok (D) VCS buna izin verecektir.

Şimdi tarihi izlemek basit; .pydiff küçük, metinsel ve basit bulunmaktadır. Bir zamanlar, bir klon (sadece şube; orada 2. bir dizüstü bilgisayar sunucusu başlat) veya daha eski bir sürüme (check-out ve bir dizüstü bilgisayar sunucusuna aktarma) vb. İhtiyacımız var.

İpuçları & Hileler

  • Ekle * .ipynb için ' .hgignore Mercurial bilmesi için', bu o dosyaları yok sayabilirsiniz
  • Sunucuyu başlatmak için ( --scriptseçenek ile) bir (bash) komut dosyası oluşturun ve sürümü izleyin
  • Bir defter kaydetme kaydetme yapar .py-File ama yok değil bunu kontrol edin.
    • Bu bir dezavantaj : Bunu unutabilirsiniz
    • Ayrıca bir özelliktir : Depo geçmişini kümelemeden bir not defterini kaydetmek (ve daha sonra devam etmek) mümkündür.

dilekler

  • Defter Kontrol Panosunda check-in / add / etc için düğmelere sahip olmak güzel olurdu
  • (Örnek olarak) için bir ödeme file@date+rev.pyyararlı olmalıdır Bunu eklemek için çok çalışmak olurdu; ve belki bir kez yapacağım. Şimdiye kadar bunu sadece elle yapıyorum.

Nasıl dan gitmek .pybir dizüstü dosya arka? Bu yaklaşımı seviyorum, ancak .ipynb-> .py-> .ipynbpotansiyel olarak kayıplı olduğu için bunu ciddiye almadım.
mforbes

Bu kolay: örneğin De Notebook-dashboard'a bırakarak yükleyin. "Çıktı verileri" dışında hiçbir şey kaybolmaz
Albert

Eğer bu doğruysa, o zaman ben bu kadar yakın fikre olacağını düşünüyorum, ama ipython tamamen geçiş verileri koruyarak hiçbir taahhütte olduğunu hatırlama görünmektedir .pyiçin .ipynbformatları. Bununla ilgili bir sorun var - belki bu tam bir çözümün temelini oluşturacaktır.
mforbes

.pyDosyalardan dosyalara dönüştürme konusunda zorlanıyorum .ipynb. nbconverthenüz bunu desteklemiyor gibi görünüyor ve ipython notebookmanuel olarak çalıştığım için bir dizüstü bilgisayar kontrol panelim yok. Bu geri dönüşümü nasıl uygulayacağınız konusunda genel önerileriniz var mı?
mforbes

Elbette .pydizüstü-bilgisayar dönüşümü gidiş-dönüş için tasarlanmamıştır. Bu gerçekten sizin için işe yarıyor olsa da, genel bir çözüm olamaz.
holdenweb

3

Böyle bir Unicode ayrıştırma hatası alırsanız, Pietro Battiston'un mükemmel komut dosyasını takip etmek için:

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)

Senaryonun başına ekleyebilirsiniz:

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

3

Bu sorunu çözen python paketi oluşturdum

https://github.com/brookisme/gitnb

Git deponuzdaki not defterlerini izlemek / güncellemek / fark etmek için git esinli bir sözdizimine sahip bir CLI sağlar.

Heres'e bir örnek

# 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 taahhüdü" nü kullandığım son adımın git deponuza bağlı olduğunu unutmayın. Aslında bir sarıcı

# 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"

Birkaç yöntem daha vardır ve her aşamada daha fazla veya daha az kullanıcı girişi gerektirecek şekilde yapılandırılabilir, ancak genel fikir budur.


3

Etrafında kazma sonra nihayet buldum Jupyter docs bu nispeten basit ön kaydet kanca . Hücre çıkış verilerini çıkarır. jupyter_notebook_config.pyDosyaya yapıştırmanız gerekir (talimatlar için aşağıya bakın).

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

Gönderen Zengin Signell cevabı :

jupyter_notebook_config.pyDosyanızı hangi dizinde bulacağınızdan emin değilseniz, jupyter --config-dir[komut istemine / terminaline] yazabilirsiniz ve dosyayı orada bulamazsanız, yazarak oluşturabilirsiniz jupyter notebook --generate-config.


1
Bu çözümün herhangi bir çıktıyı diske kaydetmeyeceğini ve sürüm kontrol sorunundan biraz bağımsız olduğunu unutmayın.
bdforbes

2

Albert & Rich'in yaptıklarını yaptım. Bunun yerine, her zaman config dosyanızı çalıştırın ipython notebook --scriptya da koyun c.FileNotebookManager.save_script = True, böylece .pynot defterinizi kaydederken her zaman (versiyonlanabilir) bir dosya oluşturulur.

Defterleri yeniden oluşturmak için (bir depoyu kontrol ettikten veya bir şubeyi değiştirdikten sonra), not defterlerimi sakladığım dizine py_file_to_notebooks.py komut dosyasını koydum .

Şimdi, bir repo kontrol ettikten sonra, sadece python py_file_to_notebooks.pyipynb dosyaları oluşturmak için çalıştırın . Şubeyi değiştirdikten sonra python py_file_to_notebooks.py -ov, mevcut ipynb dosyalarının üzerine yazmak için çalıştırmanız gerekebilir .

Sadece güvenli tarafta olmak *.ipynbiçin, .gitignoredosyanıza da eklemek iyidir .

Düzenleme: Bunu artık yapmıyorum çünkü (A) bir şubeyi her kontrol ettiğinizde not defterlerinizi py dosyalarından yeniden oluşturmanız gerekiyor ve (B) kaybettiğiniz not defterlerinde markdown gibi başka şeyler de var. Bunun yerine bir git filtresi kullanarak dizüstü bilgisayarlardan çıktıları çıkarıyorum. Bunun nasıl yapılacağı hakkında tartışma burada .


Bu fikri beğendim, ancak test ettikten sonra, .pydosyalardan geri .ipynbdönüşe dönüşümün , özellikle henüz dönüştürücü olmayan sürüm 4 dizüstü bilgisayarlarda sorunlu olduğunu gördüm . Biri şu anda v3 ithalatçı kullanmak sonra v4 dönüştürmek gerekir ve ben bu karmaşık gezi hakkında biraz endişeliyim. .pyDefter öncelikle Julia kodu ise , bir dosya çok iyi bir seçim değildir! Son olarak, --scriptkullanımdan kaldırıldı, bu yüzden kancaların gitmenin yolu olduğunu düşünüyorum.
mforbes

Bağlantınızdaki git filtresi çözümü iyi, cevabınızı buradan kopyalamanız gerekir :-)
mcarans

2

Tamam, bu yüzden şu anki en iyi çözüm gibi görünüyor, burada bir tartışmaya göre , taahhütte ipynb dosyalarından çıktıları otomatik olarak çıkarmak için bir git filtresi yapmaktır.

İşte onu çalıştırmak için yaptığım (o tartışma kopyalandı):

: Ben en son IPython alamıyor zaman bilgilendirici bir hata vermek için hafifçe cfriedline en nbstripout dosyasını modifiye https://github.com/petered/plato/blob/fb2f4e252f50c79768920d0e47b870a8d799e92b/notebooks/config/strip_notebook_output sağlar, Ve benim repo onu ekledi içinde söyle./relative/path/to/strip_notebook_output

Ayrıca, aşağıdakileri içeren repo köküne .gitattributes dosyasını ekledik:

*.ipynb filter=stripoutput

Ve bir setup_git_filters.shiçeren oluşturdu

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

Ve koştu source setup_git_filters.sh. Fantezi $ (git rev-parse ...) şey, herhangi bir (Unix) makinede deponuzun yerel yolunu bulmaktır.


1

Bu jupyter uzantısı, kullanıcıların jupyter not defterlerini doğrudan github'a itmelerini sağlar.

Lütfen buraya bakın

https://github.com/sat28/githubcommit


bunun ne yaptığını açıklayabilir misin? Dokümantasyon belli değil.
Alex Monras

Bu doğrudan bir taahhüt mesajla GitHub repoya defterleri zorlayabilir yerden jupyter defterine bir düğme eklenir @AlexMonras
sat

1

Bu Nisan-2020 ve Jupyter dizüstü bilgisayar sürüm kontrolü için birçok strateji ve araç var. İşte kullanabileceğiniz tüm araçlara hızlı bir genel bakış,

  • nbdime - Dizüstü bilgisayarların yerel olarak dağıtılması ve birleştirilmesi için güzel

  • nbstripout - Her girişten önce dizüstü bilgisayar çıktılarını otomatik olarak kaldırmak için bir git filtresi

  • jupytext - Her not defterine senkronize edilmiş bir .py tamamlayıcı dosyası tutar. Yalnızca .py dosyalarını işlersiniz

  • nbconvert - Not defterlerini bir python komut dosyasına veya HTML'ye (veya her ikisine) dönüştürün ve bu alternatif dosya türlerini uygulayın

  • ReviewNB - GitHub'daki herhangi bir taahhüt veya çekme isteği için not defteri farkını (çıktı ile birlikte) gösterir. Değişiklikleri tartışmak için not defteri hücrelerine de yorum yazılabilir (aşağıdaki ekran görüntüsü).

resim açıklamasını buraya girin

Feragatname: ReviewNB'yi oluşturdum.


0

Aşağıdaki yazıda tartışılan, not defterinin çıktısının tutulması gereken fikre ne dersiniz, onu oluşturmak uzun zaman alabileceği iddiasıyla GitHub artık not defterleri oluşturabildiğinden kullanışlıdır. .Py dosyasını dışa aktarmak için not defterleri veya git kullanmayan ekip üyeleriyle paylaşmak üzere diffs ve .html için kullanılan otomatik kaydetme kancaları vardır.

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.