Hubungan antara SciPy dan NumPy

254

SciPy tampaknya menyediakan sebagian besar (tetapi tidak semua [1]) fungsi NumPy dalam ruang namanya sendiri. Dengan kata lain, jika ada fungsi bernama numpy.foo, hampir pasti ada ascipy.foo . Sebagian besar waktu, keduanya tampak persis sama, seringkali bahkan menunjuk ke objek fungsi yang sama.

Terkadang, mereka berbeda. Untuk memberikan contoh yang muncul baru-baru ini:

  • numpy.log10adalah ufunc yang mengembalikan NaNs untuk argumen negatif;
  • scipy.log10 mengembalikan nilai kompleks untuk argumen negatif dan sepertinya bukan ufunc.

Hal yang sama dapat dikatakan tentang log, log2dan logn, tetapi bukan tentanglog1p [2].

Di sisi lain, numpy.expdan scipy.exptampaknya nama yang berbeda untuk ufunc yang sama. Ini juga berlaku untuk scipy.log1pdannumpy.log1p .

Contoh lain adalah numpy.linalg.solvevs.scipy.linalg.solve . Mereka serupa, tetapi yang terakhir menawarkan beberapa fitur tambahan di atas yang pertama.

Mengapa duplikasi yang jelas? Jika ini dimaksudkan sebagai impor grosir numpyke scipynamespace, mengapa perbedaan yang halus dalam perilaku dan fungsi yang hilang? Apakah ada logika menyeluruh yang akan membantu menjernihkan kebingungan?

[1] numpy.min, numpy.max, numpy.absdan beberapa orang lainnya tidak memiliki rekan-rekan discipy namespace.

[2] Diuji menggunakan NumPy 1.5.1 dan SciPy 0.9.0rc2.

NPE
sumber
7
Saya membaca jawaban itu all of those functions are available without additionally importing Numpykarena the intention is for users not to have to know the distinction between the scipy and numpy namespaces. Sekarang saya bertanya-tanya, karena saya mengikuti postingan tentang numpy dan scipy sedikit dan menggunakannya sendiri. Dan saya hampir selalu melihat numpy diimpor secara terpisah (seperti np). Jadi mereka gagal?
joris
8
ada beberapa perbedaan antara scipy dan numpy dalam hal-hal FFT, saya pernah digigit oleh masalah yang akhirnya dilacak ke versi scffy dan numpy dari rfft yang didefinisikan secara berbeda
wim
1
FFTs of SciPy dan NumPy berbeda. SciPy menggunakan pustaka Fortran FFTPACK, maka nama itu scipy.fftpack. NumPy menggunakan pustaka C yang disebut fftpack_lite; ia memiliki lebih sedikit fungsi dan hanya mendukung presisi ganda di NumPy. Inc renst. telah menambal numpy.fft mereka untuk menggunakan Intel MKL untuk FFT alih-alih fftpack_lite.
Sturla Molden
7
NumPy awalnya bernama scipy.core. NumPy dan SciPy adalah proyek yang terkait erat. Alasan utama pemisahan adalah untuk memastikan bahwa perpustakaan array (NumPy) ramping dan rata-rata, karena sebagian besar SciPy tidak selalu diperlukan. Juga, ada keputusan di antara para ilmuwan untuk pensiun paket array numerik (MIT) dan numarray (NASA) yang mendukung scipy.core, dan dengan demikian mendapat nama NumPy. SciPy masih belum mencapai 1,0, sedangkan NumPy saat ini dirilis sebagai 1.8.1. NumPy memiliki beberapa fasilitas untuk FFT dan aljabar linier, tetapi tidak seluas SciPy.
Sturla Molden
@SturlaMolden senang mengetahui tentang Enthought, apakah Anda tahu jika Anaconda mengoptimalkan keduanya atau hanya numpy?
dashesy

Jawaban:

138

Terakhir kali saya memeriksanya, __init__metode scipy mengeksekusi a

from numpy import *

sehingga seluruh namespace numpy dimasukkan ke dalam scipy ketika modul scipy diimpor.

The log10perilaku yang Anda gambarkan adalah menarik, karena kedua versi berasal dari numpy. Satu adalah a ufunc, yang lain adalah numpy.libfungsi. Mengapa Scipy lebih memilih fungsi perpustakaan daripada ufunc, saya tidak tahu dari atas kepala saya.


EDIT: Sebenarnya, saya bisa menjawab log10pertanyaan itu. Melihat dalam __init__metode scipy saya melihat ini:

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

The log10Fungsi Anda dapatkan di scipy berasal dari numpy.lib.scimath. Melihat kode itu, tertulis:

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

Tampaknya modul overlay yang ufuncs dasar numpy untuk sqrt, log, log2, logn, log10, power, arccos, arcsin, dan arctanh. Itu menjelaskan perilaku yang Anda lihat. Alasan desain yang mendasari mengapa hal itu dilakukan seperti itu mungkin dimakamkan di pos milis di suatu tempat.

talonmies
sumber
10
Setelah bekerja penuh waktu dengan paket-paket ini untuk sementara waktu, inilah perasaan yang saya dapatkan tentang itu: NumPy dimaksudkan sebagai perpustakaan untuk array numerik, untuk digunakan oleh siapa saja yang membutuhkan objek seperti itu di Python. SciPy dimaksudkan sebagai perpustakaan untuk ilmuwan / insinyur, sehingga bertujuan untuk matematika teoretis yang lebih kuat (dengan demikian termasuk versi bilangan kompleks log10 dan sejenisnya). Kebingungan utama berasal dari kenyataan bahwa NumPy mempertahankan banyak sub-modul lama (yang seharusnya menjadi Scipy) yang dimasukkan pada saat ketika demarkasi antara SciPy / NumPy tidak sejelas sekarang ini.
PhilMacKay
@ PhilMacKay Hai Phil, saya membaca ini dan posting Anda yang lain khusus untuk pertanyaan numpy / licik ini dari 2013. Pertanyaan saya adalah apakah pendapat Anda masih terkini, seperti yang tercantum dalam komentar Anda di atas? saya melihat poster mengatakan ada beberapa non-setara dalam scipy dan daftar abs, max dan min sebagai contoh, tapi saya mengerti bahwa abs hanyalah alias untuk numpy.absolute dan ada scipy.absolute, scipy.maximum dan scipy .minimum. Jadi dalam pengalaman Anda hingga sekarang, apakah Anda pernah perlu mengimpor numpy jika Anda sudah membutuhkan scipy?
Dan Boschen
@ PhilMacKay Tampaknya konsensus umum adalah menggunakan pustaka submisi dari SciPy untuk kasus penggunaannya yang relevan, dan kemudian untuk operasi inti NumPy untuk mengimpor NumPy secara khusus (alih-alih SciPy tingkat atas yang seharusnya perlu Anda impor ). Untuk beberapa alasan ini dinyatakan oleh orang lain serta dokumentasi SciPy itu sendiri sebagai praktik pengkodean yang lebih baik dan saya mencoba memahami mengapa itu penting. Saya menganggap itu karena itu adalah masalah konvensi dan karena itu mudah dibaca. Apa pendapat Anda saat ini?
Dan Boschen
@DanBoschen Per November 2018, saya masih mendukung komentar saya di atas. Mengimpor SciPy ketika hanya NumPy yang dibutuhkan mungkin sedikit berlebihan. Di sisi lain, NumPy diimpor ketika SciPy dimuat, sehingga tidak perlu mengimpor NumPy selain SciPy. Tentu saja, ada argumen yang bagus untuk mengikuti dokumentasi, jadi silakan melakukan apa yang paling relevan dengan situasi Anda sendiri.
PhilMacKay
@ PhilMacKay Terima kasih atas masukan Anda. Setelah memikirkannya menurut dugaan saya mengapa disarankan untuk mengimpor numpy (meskipun semuanya dapat dilakukan dalam scipy) adalah masalah konvensi dan karena itu keterbacaan untuk kode bersama. Jika semua kode khusus numpy terikat ke perpustakaan numpy secara khusus, itu juga dapat lebih mudah terputus dari terikat ke perpustakaan yang lebih besar yang mencakup lebih banyak yang mungkin tidak selalu diperlukan. Yang mengatakan pemikiran saya (untuk pendekatan saya sendiri) adalah mengimpor numpy dan kemudian BUKAN mengimpor tingkat atas cipy tetapi hanya mengimpor subpackage scipy sesuai kebutuhan.
Dan Boschen
52

Dari Panduan Referensi SciPy:

... semua fungsi Numpy telah dimasukkan ke dalam scipy namespace sehingga semua fungsi tersebut tersedia tanpa tambahan mengimpor Numpy.

Tujuannya adalah agar pengguna tidak harus mengetahui perbedaan antara ruang nama scipydan numpyruang nama, meskipun tampaknya Anda telah menemukan pengecualian.

John D. Cook
sumber
50

Tampaknya dari FAQ SciPy bahwa beberapa fungsi dari NumPy ada di sini karena alasan historis sementara itu hanya harus dalam SciPy:

Apa perbedaan antara NumPy dan SciPy?

Dalam dunia yang ideal, NumPy tidak akan berisi apa pun selain tipe data array dan operasi paling dasar: pengindeksan, pengurutan, pembentukan kembali, fungsi dasar elemen, dan lain-lain. Semua kode numerik akan berada di SciPy. Namun, salah satu tujuan penting NumPy adalah kompatibilitas, sehingga NumPy mencoba untuk mempertahankan semua fitur yang didukung oleh salah satu pendahulunya. Dengan demikian NumPy berisi beberapa fungsi aljabar linier, meskipun ini lebih baik milik SciPy. Bagaimanapun, SciPy berisi versi yang lebih lengkap dari modul aljabar linier, serta banyak algoritma numerik lainnya. Jika Anda melakukan komputasi ilmiah dengan python, Anda mungkin harus menginstal NumPy dan SciPy. Sebagian besar fitur baru termasuk dalam SciPy dan bukan NumPy.

Itu menjelaskan mengapa scipy.linalg.solvemenawarkan beberapa fitur tambahannumpy.linalg.solve .

Saya tidak melihat jawaban SethMMorton untuk pertanyaan terkait

PhML
sumber
12

Ada komentar singkat di akhir pengantar dokumentasi SciPy :

Perintah lain yang bermanfaat adalah source. Ketika diberi fungsi yang ditulis dengan Python sebagai argumen, itu mencetak daftar kode sumber untuk fungsi itu. Ini bisa membantu dalam mempelajari tentang suatu algoritma atau memahami dengan tepat apa yang dilakukan fungsi dengan argumennya. Juga jangan lupa tentang dir perintah Python yang dapat digunakan untuk melihat namespace dari suatu modul atau paket.

Saya pikir ini akan memungkinkan seseorang dengan pengetahuan yang cukup tentang semua paket yang terlibat untuk memisahkan apa perbedaan antara beberapa fungsi scipy dan numpy (tidak membantu saya dengan pertanyaan log10 sama sekali). Saya benar-benar tidak memiliki pengetahuan itu tetapi sourcemenunjukkan hal itu scipy.linalg.solvedan numpy.linalg.solveberinteraksi dengan Lapack dengan cara yang berbeda;

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))

Ini juga posting pertama saya jadi jika saya harus mengubah sesuatu di sini, beri tahu saya.

dshort
sumber
Pembungkus yang mendasarinya sangat berbeda. NumPy menggunakan lapisan tipis yang ditulis dalam C. SciPy menggunakan lapisan yang dibuat secara otomatis oleh f2py. SciPy selalu menghubungkan dengan perpustakaan LAPACK eksternal. Penggunaan NumPy memiliki lapack_lite f2c'd sendiri dalam kasus LAPACK eksternal tidak ditemukan.
Sturla Molden
8

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

Kode Numerik diadaptasi agar lebih mudah dikelola dan fleksibel untuk mengimplementasikan fitur-fitur baru Numarray. Proyek baru ini adalah bagian dari SciPy. Untuk menghindari menginstal seluruh paket hanya untuk mendapatkan objek array, paket baru ini dipisahkan dan disebut NumPy.

scipybergantung pada numpydan mengimpor banyak numpyfungsi ke dalam namespace-nya untuk kenyamanan.

Mu Mind
sumber
4

Mengenai paket linalg - fungsi cipy akan memanggil lapack dan blas, yang tersedia dalam versi yang sangat dioptimalkan pada banyak platform dan menawarkan kinerja yang sangat baik, terutama untuk operasi pada matriks padat yang cukup besar. Di sisi lain, mereka bukanlah perpustakaan yang mudah dikompilasi, membutuhkan fortran compiler dan banyak penyesuaian platform khusus untuk mendapatkan kinerja penuh. Oleh karena itu, numpy menyediakan implementasi sederhana dari banyak fungsi aljabar linear umum yang seringkali cukup baik untuk banyak tujuan.

DaveP
sumber
numpy 1.10 memiliki modul yang bagus dual: "Modul ini harus digunakan untuk fungsi baik di numpy dan scipy jika Anda ingin menggunakan versi numpy jika tersedia tetapi versi cipy sebaliknya." Penggunaan ---from numpy.dual import fft, inv
denis
1

Dari Ceramah tentang ' Ekonomi Kuantitatif '

SciPy adalah paket yang berisi berbagai alat yang dibangun di atas NumPy, menggunakan tipe data lariknya dan fungsionalitas terkait

Bahkan, ketika kita mengimpor SciPy kita juga mendapatkan NumPy, seperti yang dapat dilihat dari file inisialisasi SciPy

# 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')

Namun, itu lebih umum dan praktik yang lebih baik untuk menggunakan fungsi NumPy secara eksplisit

import numpy as np

a = np.identity(3)

Apa yang berguna dalam SciPy adalah fungsionalitas dalam sub-paketnya

  • scipy.optimize, scipy.integrate, scipy.stats, dll.
Vlad Bezden
sumber
1
Saya melihat komentar Anda bahwa itu adalah praktik yang lebih baik untuk menggunakan fungsi NumPy secara eksplisit, dan saya melihat ini digaungkan di tempat lain termasuk dalam tutorial SciPy, tetapi mengapa praktik ini lebih baik? Sepertinya tidak ada yang menjawab itu. Jika Anda sudah mengimpor SciPy dan itu termasuk fungsi NumPy, mengapa lebih baik mengimpor NumPy? Apakah ketika kita mengimpor subpackage di SciPy, kita TIDAK mengimpor level atas, dan karena itu alih-alih mengambil langkah untuk mengimpor SciPy secara khusus, kita hanya perlu mengimpor Numpy untuk fungsi pemrosesan array inti itu?
Dan Boschen
1

Selain itu FAQ SciPy yang menjelaskan duplikasi ini terutama untuk kompatibilitas mundur, selanjutnya dijelaskan dalam dokumentasi NumPy untuk mengatakan bahwa

Opsional, rutinitas berakselerasi SciPy (numpy.dual)

Alias ​​untuk fungsi yang mungkin dipercepat oleh Scipy.

SciPy dapat dibangun untuk menggunakan pustaka yang dipercepat atau lebih baik untuk FFT, aljabar linier, dan fungsi khusus. Modul ini memungkinkan pengembang untuk secara transparan mendukung fungsi-fungsi yang dipercepat ini ketika SciPy tersedia tetapi masih mendukung pengguna yang hanya menginstal NumPy.

Untuk singkatnya, ini adalah:

  • Aljabar linier
  • FFT
  • Fungsi Bessel yang Dimodifikasi dari jenis pertama, pesan 0

Juga, dari Tutorial SciPy :

Level atas SciPy juga berisi fungsi-fungsi dari NumPy dan numpy.lib.scimath. Namun, lebih baik menggunakannya langsung dari modul NumPy sebagai gantinya.

Jadi, untuk aplikasi baru, Anda harus memilih versi NumPy dari operasi array yang diduplikasi di tingkat atas SciPy. Untuk domain yang tercantum di atas, Anda harus memilih yang ada di SciPy dan memeriksa kompatibilitas jika perlu di NumPy.

Dalam pengalaman pribadi saya, sebagian besar fungsi array yang saya gunakan ada di tingkat atas NumPy (kecuali untuk random). Namun, semua rutinitas khusus domain ada di subpackages SciPy, jadi saya jarang menggunakan apa pun dari tingkat atas SciPy.

jbbiomed
sumber