SciPy ve NumPy arasındaki ilişki


254

SciPy, NumPy işlevlerinin çoğunu (ancak hepsini değil [1]) kendi ad alanında sağlıyor gibi görünüyor. Başka bir deyişle, adında bir işlev numpy.foovarsa, neredeyse kesinlikle bir scipy.foo. Çoğu zaman, ikisi tamamen aynı gibi görünür, çoğu zaman aynı işlev nesnesine bile işaret eder.

Bazen farklılar. Son zamanlarda ortaya çıkan bir örnek vermek gerekirse:

  • numpy.log10negatif argümanlar için NaN'leri döndüren bir ufunc ;
  • scipy.log10 negatif argümanlar için karmaşık değerler döndürür ve bir ufunc gibi görünmez.

Yaklaşık olarak aynı söylenebilir log, log2ve lognancak yaklaşık log1p[2].

Öte yandan, numpy.expve scipy.expaynı ufunc için farklı isimler olarak görünmektedir. Bu aynı zamanda doğrudur scipy.log1pve numpy.log1p.

Bir başka örnek ise numpy.linalg.solvevs scipy.linalg.solve. Benzerler, ancak ikincisi birincisine göre bazı ek özellikler sunuyor.

Neden görünen çoğaltma? Bu, ad numpyalanına toptan bir ithalat scipyyapmaksa, neden davranıştaki küçük farklılıklar ve eksik işlevler? Karışıklığın giderilmesine yardımcı olacak bazı kapsayıcı mantık var mı?

[1] numpy.min, numpy.max, numpy.absve birkaç başka hiçbir karşılığı var scipyad.

[2] NumPy 1.5.1 ve SciPy 0.9.0rc2 kullanılarak test edilmiştir.


7
Cevapları okudum all of those functions are available without additionally importing Numpyçünkü the intention is for users not to have to know the distinction between the scipy and numpy namespaces. Şimdi merak ediyorum, çünkü numpy ve scipy hakkındaki mesajları takip ediyorum ve kendim kullanıyorum. Ve neredeyse her zaman numpy'nin ayrı olarak ithal edildiğini görüyorum (np olarak). Yani başarısız oldular?
joris

8
scipy ve numpy arasında bazı farklılıklar var FFT şeyler, bir keresinde nihayet scipy ve numpy'nin farklı tanımlanmış rfft versiyonunu izleyen bir sorun tarafından ısırıldım
wim

1
SciPy ve NumPy'nin FFT'leri farklıdır. SciPy, Fortran kütüphanesi FFTPACK'i kullanır, bu nedenle scipy.fftpack adı. NumPy, fftpack_lite adlı bir C kütüphanesi kullanır; daha az işlevi vardır ve NumPy'de yalnızca çift duyarlığı destekler. Enthought inc. numft.fft dosyalarını fftpack_lite yerine FFT'ler için Intel MKL kullanmak üzere yamalı.
Sturla Molden

7
NumPy başlangıçta scipy.core olarak adlandırıldı. NumPy ve SciPy yakından ilgili projelerdir. Ayırma işleminin ana nedeni, dizi kütüphanesinin (NumPy) yalın ve ortalama olmasını sağlamaktır, çünkü SciPy'nin yığınına her zaman ihtiyaç duyulmaz. Ayrıca, bilim adamları arasında scipy.core lehine dizi (MIT) ve numarray (NASA) dizi paketlerini emekliye ayırmaya karar verdiler ve bu nedenle NumPy adını aldı. SciPy hala 1.0'a ulaşmamışken, NumPy şu anda 1.8.1 olarak piyasaya sürüldü. NumPy, FFT ve lineer cebir için bazı olanaklara sahiptir, ancak SciPy kadar geniş değildir.
Sturla Molden

@SturlaMolden Enthought hakkında bilmek güzel, Anaconda'nın her ikisini de optimize edip etmediğini biliyor musunuz?
dashesy

Yanıtlar:


138

En son kontrol ettiğimde, scipy __init__yöntemi bir

from numpy import *

böylece scpyy modülü içe aktarıldığında numpy ad alanının tamamı scipy'ye dahil edilir.

Tanımladığınız log10davranış ilginç, çünkü her iki sürüm de numpy'den geliyor. Biri bir ufunc, diğeri bir numpy.libişlevdir. Scipy neden kütüphane fonksiyonunu tercih ediyor, ufunckafamın üstünü bilmiyorum.


EDIT: Aslında, soruya cevap verebilirim log10. Scipy __init__yöntemine bakarak bunu görüyorum:

# Import numpy symbols to scipy name space
import numpy as _num
from numpy import oldnumeric
from numpy import *
from numpy.random import rand, randn
from numpy.fft import fft, ifft
from numpy.lib.scimath import *

log10Eğer SciPy olsun fonksiyonu geliyor numpy.lib.scimath. Bu koda bakarak şöyle diyor:

"""
Wrapper functions to more user-friendly calling of certain math functions
whose output data-type is different than the input data-type in certain
domains of the input.

For example, for functions like log() with branch cuts, the versions in this
module provide the mathematically valid answers in the complex plane:

>>> import math
>>> from numpy.lib import scimath
>>> scimath.log(-math.exp(1)) == (1+1j*math.pi)
True

Similarly, sqrt(), other base logarithms, power() and trig functions are
correctly handled.  See their respective docstrings for specific examples.
"""

O modül bindirmeler için taban numpy ufuncs görünüyor sqrt, log, log2, logn, log10, power, arccos, arcsin, ve arctanh. Bu gördüğünüz davranışı açıklar. Bunun böyle yapılmasının altında yatan tasarım nedeni muhtemelen bir yerde bir posta listesi postasına gömülmüştür.


10
Bir süre bu paketlerle tam zamanlı çalıştıktan sonra, bunun hakkında hissediyorum: NumPy, sayısal diziler için bir kütüphane, Python'da böyle bir nesneye ihtiyaç duyan herkes tarafından kullanılacak. SciPy'nin bilim adamları / mühendisler için bir kütüphane olması amaçlanmıştır, bu yüzden daha titiz teorik matematik hedefler (böylece log10 ve benzeri karmaşık sayı versiyonu dahil). Ana karışıklık, NumPy'nin SciPy / NumPy arasındaki sınırlamanın bugünkü kadar net olmadığı zamanlarda dahil edilen birçok eski alt modülü (Scipy'ye girmiş olması gerekir) tutması gerçeğinden kaynaklanmaktadır.
PhilMacKay

@PhilMacKay Merhaba Phil, bu ve 2013 bu numpy / scipy soruya özgü diğer yazı okudum. Benim sorum yukarıdaki yorumda da belirtildiği gibi görüş hala güncel olup olmadığını? posterin scipy'de eşdeğer olmayan bazı şeyler olduğunu ve abs, max ve min'i örnek olarak listelediğini görüyorum, ancak abs'in numpy.absolute için sadece bir takma ad olduğunu ve bir scipy.absolute, scipy.maximum ve scipy olduğunu anlıyorum. .minimum. Yani şimdiye kadar deneyimlerinizde, zaten scipy'ye ihtiyacınız varsa, numpy'yi içe aktarmanız gerekiyor mu?
Dan Boschen

@PhilMacKay Genel fikir birliği, SciPy'nin alt modül kitaplıklarını ilgili kullanım durumları için kullanmak ve daha sonra çekirdek NumPy işlemlerinin NumPy'yi özel olarak içe aktarması (aksi takdirde içe aktarmanız gereken üst düzey SciPy yerine) ). Bazı nedenlerden dolayı bu, diğerleri tarafından ve SciPy belgelerinin kendisi tarafından daha iyi kodlama uygulaması olarak belirtilmiştir ve bunun neden önemli olduğunu anlamaya çalışıyorum. Bence bu bir konvansiyon ve dolayısıyla okunabilirlik meselesidir. Şu anki fikrin nedir?
Dan Boschen

@DanBoschen Kasım 2018 itibarıyla yukarıdaki yorumumun yanındayım. Yalnızca NumPy gerektiğinde SciPy'i içe aktarmak biraz fazla olabilir. Öte yandan, NumPy SciPy yüklendiğinde içe aktarılır, bu nedenle SciPy'ye ek olarak NumPy'yi içe aktarmaya gerek yoktur. Tabii ki, belgeleri takip etmek için iyi argümanlar var, bu yüzden kendi durumunuzda en alakalı olanı yapmaktan çekinmeyin.
18:54, PhilMacKay

@PhilMacKay Girişiniz için teşekkürler. Tahminimce niçin numpy almanın önerildiğini düşünmek (her şey scipy'de yapılabilir olsa da) bir konvansiyon ve dolayısıyla paylaşılan kod için okunabilirlik meselesidir. Tüm numpy'ye özgü kod özel olarak numpy kütüphanesine bağlıysa, her zaman gerekmeyebilecek çok daha fazlasını içeren daha geniş scipy kütüphanesine bağlanmaktan daha kolay kırılabilir. Benim düşüncem (kendi yaklaşımım için) numpy ithal ve sonra üst düzey scipy ithal DEĞİL ama sadece gerektiği gibi scipy alt paketleri almak olduğunu söyledi.
Dan Boschen

52

SciPy Başvuru Kılavuzu'ndan:

... Numpy işlevlerinin scipy tümü ad alanına dahil edilmiştir, böylece bu işlevlerin tümü Numpy'yi içe aktarmadan kullanılabilir.

Amaç, kullanıcılar için scipyve numpyad alanları arasındaki farkı bilmek zorunda olmamaktır , ancak görünüşe göre bir istisna bulmuşsunuzdur.


50

Gelen görünüyor scipy SSS numpy bazı fonksiyonlar sadece SciPy içinde olması gerekirken tarihi nedenlerden ötürü burada olduğunu:

NumPy ve SciPy arasındaki fark nedir?

İdeal bir dünyada, NumPy dizi veri türü ve en temel işlemlerden başka bir şey içermez: indeksleme, sıralama, yeniden şekillendirme, temel elemanwise fonksiyonlar, vb. Tüm sayısal kodlar SciPy'de bulunur. Bununla birlikte, NumPy'nin önemli hedeflerinden biri uyumluluktur, bu nedenle NumPy öncekilerden biri tarafından desteklenen tüm özellikleri korumaya çalışır. Bu nedenle, NumPy, SciPy'ye daha düzgün bir şekilde ait olsa da, bazı doğrusal cebir fonksiyonları içerir. Her durumda, SciPy lineer cebir modüllerinin daha tam özellikli versiyonlarını ve diğer birçok sayısal algoritmayı içerir. Python ile bilimsel hesaplama yapıyorsanız, muhtemelen hem NumPy hem de SciPy'yi yüklemelisiniz. Çoğu yeni özellik NumPy yerine SciPy'ye aittir.

Bu, neden scipy.linalg.solvebazı ek özellikler sunduğunu açıklıyor numpy.linalg.solve.

SethMMorton'un ilgili soruya cevabını görmedim


12

SciPy belgelerine girişin sonunda kısa bir yorum var :

Başka bir yararlı komut source. Bağımsız değişken olarak Python'da yazılmış bir işlev verildiğinde, o işlevin kaynak kodunun bir listesini yazdırır. Bu, bir algoritmayı öğrenmede veya bir işlevin argümanlarıyla tam olarak ne yaptığını anlamada yardımcı olabilir. Ayrıca, bir modül veya paketin ad alanına bakmak için kullanılabilecek Python komut dizinini de unutmayın.

Bu, ilgili tüm paketler hakkında yeterli bilgiye sahip birisinin, bazı scipy ve numpy işlevleri arasındaki farkları tam olarak ayırmasına izin vereceğini düşünüyorum (log10 sorusunda bana yardımcı olmadı). Kesinlikle bu bilgiye sahip değilim ama sourcebunu gösterir scipy.linalg.solveve numpy.linalg.solvelapack ile farklı şekillerde etkileşime girer;

Python 2.4.3 (#1, May  5 2011, 18:44:23) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-50)] on linux2
>>> import scipy
>>> import scipy.linalg
>>> import numpy
>>> scipy.source(scipy.linalg.solve)
In file: /usr/lib64/python2.4/site-packages/scipy/linalg/basic.py

def solve(a, b, sym_pos=0, lower=0, overwrite_a=0, overwrite_b=0,
          debug = 0):
    """ solve(a, b, sym_pos=0, lower=0, overwrite_a=0, overwrite_b=0) -> x

    Solve a linear system of equations a * x = b for x.

    Inputs:

      a -- An N x N matrix.
      b -- An N x nrhs matrix or N vector.
      sym_pos -- Assume a is symmetric and positive definite.
      lower -- Assume a is lower triangular, otherwise upper one.
               Only used if sym_pos is true.
      overwrite_y - Discard data in y, where y is a or b.

    Outputs:

      x -- The solution to the system a * x = b
    """
    a1, b1 = map(asarray_chkfinite,(a,b))
    if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]:
        raise ValueError, 'expected square matrix'
    if a1.shape[0] != b1.shape[0]:
        raise ValueError, 'incompatible dimensions'
    overwrite_a = overwrite_a or (a1 is not a and not hasattr(a,'__array__'))
    overwrite_b = overwrite_b or (b1 is not b and not hasattr(b,'__array__'))
    if debug:
        print 'solve:overwrite_a=',overwrite_a
        print 'solve:overwrite_b=',overwrite_b
    if sym_pos:
        posv, = get_lapack_funcs(('posv',),(a1,b1))
        c,x,info = posv(a1,b1,
                        lower = lower,
                        overwrite_a=overwrite_a,
                        overwrite_b=overwrite_b)
    else:
        gesv, = get_lapack_funcs(('gesv',),(a1,b1))
        lu,piv,x,info = gesv(a1,b1,
                             overwrite_a=overwrite_a,
                             overwrite_b=overwrite_b)

    if info==0:
        return x
    if info>0:
        raise LinAlgError, "singular matrix"
    raise ValueError,\
          'illegal value in %-th argument of internal gesv|posv'%(-info)

>>> scipy.source(numpy.linalg.solve)
In file: /usr/lib64/python2.4/site-packages/numpy/linalg/linalg.py

def solve(a, b):
    """
    Solve the equation ``a x = b`` for ``x``.

    Parameters
    ----------
    a : array_like, shape (M, M)
        Input equation coefficients.
    b : array_like, shape (M,)
        Equation target values.

    Returns
    -------
    x : array, shape (M,)

    Raises
    ------
    LinAlgError
        If `a` is singular or not square.

    Examples
    --------
    Solve the system of equations ``3 * x0 + x1 = 9`` and ``x0 + 2 * x1 = 8``:

    >>> a = np.array([[3,1], [1,2]])
    >>> b = np.array([9,8])
    >>> x = np.linalg.solve(a, b)
    >>> x
    array([ 2.,  3.])

    Check that the solution is correct:

    >>> (np.dot(a, x) == b).all()
    True

    """
    a, _ = _makearray(a)
    b, wrap = _makearray(b)
    one_eq = len(b.shape) == 1
    if one_eq:
        b = b[:, newaxis]
    _assertRank2(a, b)
    _assertSquareness(a)
    n_eq = a.shape[0]
    n_rhs = b.shape[1]
    if n_eq != b.shape[0]:
        raise LinAlgError, 'Incompatible dimensions'
    t, result_t = _commonType(a, b)
#    lapack_routine = _findLapackRoutine('gesv', t)
    if isComplexType(t):
        lapack_routine = lapack_lite.zgesv
    else:
        lapack_routine = lapack_lite.dgesv
    a, b = _fastCopyAndTranspose(t, a, b)
    pivots = zeros(n_eq, fortran_int)
    results = lapack_routine(n_eq, n_rhs, a, n_eq, pivots, b, n_eq, 0)
    if results['info'] > 0:
        raise LinAlgError, 'Singular matrix'
    if one_eq:
        return wrap(b.ravel().astype(result_t))
    else:
        return wrap(b.transpose().astype(result_t))

Bu da benim ilk yazım, bu yüzden burada bir şey değiştirirsem lütfen bana bildirin.


Alttaki sarmalayıcılar çok farklıdır. NumPy, C ile yazılmış ince bir katman kullanır. SciPy, f2py tarafından otomatik olarak oluşturulan bir katman kullanır. SciPy her zaman harici bir LAPACK kütüphanesine bağlanır. Harici bir LAPACK bulunmaması durumunda NumPy kullanımlarının kendi f2c'd lapack_lite özelliği vardır.
Sturla Molden

8

Wikipedia'dan ( http://en.wikipedia.org/wiki/NumPy#History ):

Sayısal kod, Numarray'ın yeni özelliklerini uygulamak için yeterince bakım ve esneklik sağlayacak şekilde uyarlanmıştır. Bu yeni proje SciPy'nin bir parçasıydı. Bir dizi nesnesini almak için bir paketin tamamını yüklemekten kaçınmak için, bu yeni paket ayrıldı ve NumPy olarak adlandırıldı.

scipygüvenir numpyve numpykolaylık sağlamak için birçok işlevi kendi ad alanına alır.


4

Linalg paketi ile ilgili olarak, scipy fonksiyonları, birçok platformda yüksek düzeyde optimize edilmiş versiyonlarda bulunan ve özellikle oldukça büyük yoğun matrislerdeki işlemler için çok iyi performans sunan lapack ve blas'ı çağırır. Öte yandan, derlenmesi kolay kütüphaneler değildir, tam bir performans elde etmek için bir fortran derleyici ve platforma özel ince ayarlar gerektirir. Bu nedenle, numpy genellikle birçok amaç için yeterince iyi olan birçok ortak doğrusal cebir fonksiyonunun basit uygulamalarını sağlar.


numpy 1.10'un hoş bir modülü var dual: "Mümkünse numpy sürümünü ancak scipy sürümünü kullanmak istiyorsanız bu modül hem numpy hem de scipy işlevlerinde kullanılmalıdır." Kullanım ---from numpy.dual import fft, inv
denis

1

' Nicel Ekonomi Üzerine Derslerden '

SciPy, dizi veri türünü ve ilgili işlevselliğini kullanarak NumPy'nin üzerine inşa edilmiş çeşitli araçlar içeren bir pakettir

Aslında, SciPy'i içe aktardığımızda SciPy başlatma dosyasından da görülebileceği gibi NumPy'yi de alıyoruz

# Import numpy symbols to scipy name space
import numpy as _num
linalg = None
from numpy import *
from numpy.random import rand, randn
from numpy.fft import fft, ifft
from numpy.lib.scimath import *

__all__  = []
__all__ += _num.__all__
__all__ += ['randn', 'rand', 'fft', 'ifft']

del _num
# Remove the linalg imported from numpy so that the scipy.linalg package can be
# imported.
del linalg
__all__.remove('linalg')

Ancak, NumPy işlevselliğini açıkça kullanmak daha yaygın ve daha iyi bir uygulamadır

import numpy as np

a = np.identity(3)

SciPy'de kullanışlı olan, alt paketlerindeki işlevselliktir

  • scipy.optimize, scipy.integrate, scipy.stats, vb.

1
NumPy işlevselliğini açıkça kullanmanın daha iyi bir uygulama olduğu yorumunuzu görüyorum ve bu SciPy öğreticisinde de dahil olmak üzere başka bir yerde yankılandığını görüyorum, ama bu neden daha iyi bir uygulama? Kimse buna cevap vermiyor gibi görünüyor. Zaten SciPy içe aktarıyorsanız ve NumPy işlevini içeriyorsa, yine de NumPy'yi içe aktarmak neden daha iyidir? SciPy'de bir alt paketi içe aktardığımızda, en üst seviyeyi ithal etmiyor muyuz ve bu nedenle SciPy'yi özel olarak almak için adım atmak yerine, bu çekirdek dizi işleme işlevleri için Numpy'yi içe aktarmamız gerekir mi?
Dan Boschen

1

Çoğaltmayı açıklayan SciPy SSS'ye ek olarak, geriye dönük uyumluluk içindir, NumPy belgelerinde ayrıca

İsteğe bağlı olarak SciPy hızlandırmalı rutinler (numpy.dual)

Scipy tarafından hızlandırılabilen işlevler için takma adlar.

SciPy, FFT'ler, lineer cebir ve özel işlevler için hızlandırılmış veya başka şekilde geliştirilmiş kütüphaneler kullanmak üzere oluşturulabilir. Bu modül, geliştiricilerin SciPy kullanılabilir olduğunda bu hızlandırılmış işlevleri şeffaf bir şekilde desteklemelerine izin verir, ancak yine de sadece NumPy'yi yüklemiş olan kullanıcıları destekler.

Kısacası, bunlar:

  • Lineer Cebir
  • FFT
  • Birinci tür Modifiye Bessel fonksiyonu, sipariş 0

Ayrıca, SciPy Dersinde :

SciPy'nin en üst seviyesi NumPy ve numpy.lib.scimath işlevlerini de içerir. Ancak, bunları doğrudan NumPy modülünden kullanmak daha iyidir.

Bu nedenle, yeni uygulamalar için, SciPy'nin en üst düzeyinde çoğaltılan dizi işlemlerinin NumPy sürümünü tercih etmelisiniz. Yukarıda listelenen etki alanları için SciPy'de bulunanları tercih etmeli ve gerekirse NumPy'de geriye dönük uyumluluğu kontrol etmelisiniz.

Kişisel tecrübelerime göre, kullandığım dizi fonksiyonlarının çoğu NumPy'nin en üst seviyesinde (hariç random) var. Ancak, etki alanına özgü tüm rutinler SciPy'nin alt paketlerinde bulunur, bu yüzden nadiren SciPy'nin üst düzeyinden bir şey kullanırım.

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.