{"id":28639453,"url":"https://github.com/scisharp/numpy.net","last_synced_at":"2025-06-12T19:40:33.089Z","repository":{"id":34917001,"uuid":"189782132","full_name":"SciSharp/Numpy.NET","owner":"SciSharp","description":"C#/F# bindings for NumPy - a fundamental library for scientific computing, machine learning and AI","archived":false,"fork":false,"pushed_at":"2025-03-24T06:50:55.000Z","size":57391,"stargazers_count":729,"open_issues_count":16,"forks_count":100,"subscribers_count":28,"default_branch":"main","last_synced_at":"2025-06-03T18:18:14.474Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SciSharp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-01T22:16:22.000Z","updated_at":"2025-05-28T04:31:14.000Z","dependencies_parsed_at":"2024-01-14T17:05:47.656Z","dependency_job_id":"519ebc83-3619-44d8-800b-272e3c2c4ede","html_url":"https://github.com/SciSharp/Numpy.NET","commit_stats":{"total_commits":172,"total_committers":7,"mean_commits":"24.571428571428573","dds":0.03488372093023251,"last_synced_commit":"bb3666716a3679060ca8e8622195aec8cd9063d4"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/SciSharp/Numpy.NET","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SciSharp%2FNumpy.NET","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SciSharp%2FNumpy.NET/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SciSharp%2FNumpy.NET/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SciSharp%2FNumpy.NET/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SciSharp","download_url":"https://codeload.github.com/SciSharp/Numpy.NET/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SciSharp%2FNumpy.NET/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259520285,"owners_count":22870415,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-12T19:40:26.167Z","updated_at":"2025-06-12T19:40:33.069Z","avatar_url":"https://github.com/SciSharp.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"![logo](doc/img/numpy.net.logo512.png)\u003ca href=\"http://scisharpstack.org\"\u003e\u003cimg src=\"https://github.com/SciSharp/SciSharp/blob/master/art/scisharp_badge.png\" width=\"200\" height=\"200\" align=\"right\" /\u003e\u003c/a\u003e\n\n**Numpy.NET** is the most complete .NET binding for [NumPy](https://www.numpy.org/), which is a fundamental library for scientific computing, machine learning and AI in Python. Numpy.NET empowers .NET developers with extensive functionality including multi-dimensional arrays and matrices, linear algebra, FFT and many more via a compatible strong typed API. Several other SciSharp projects like [Keras.NET](https://github.com/SciSharp/Keras.NET) and [Torch.NET](https://github.com/SciSharp/Torch.NET) depend on Numpy.NET. \n\n## Example\n\nCheck out this example which uses `numpy` operations to fit a two-layer neural network to random data by manually implementing the forward and backward passes through the network.\n\n![Numpy Neural Network in C# and in Python](doc/img/cs_vs_py2.png)\n\nNumpy and Intellisense: a developer-friendly combination:\n\n![Numpy Intellisense](doc/img/numpy_intellisense.png)\n\n## Installation\nIf you want to use Numpy.NET you have two options:\n\n### Numpy.dll\nJust reference [Numpy.dll](https://www.nuget.org/packages/Numpy/) via Nuget, set your **build configuration to x64** and you are good to go. Thanks to [Python.Included](https://github.com/henon/Python.Included) it doesn't require a local Python installation or will not clash with existing installations. \n\n### Numpy.Bare.dll \nIn certain use cases you might not want the packaged Python and NumPy packages. In that case you reference [Numpy.Bare.dll](https://www.nuget.org/packages/Numpy.Bare/) via Nuget. Depending on the Numpy.Bare nuget version will need Python 3.5, 3.6 or 3.7 and Numpy 1.16 installed for it to work. The first two digits of the Numpy.Bare version indicate which Python version is needed for it to run (i.e. Numpy.Bare v3.6.1.1 needs Python 3.6 installed). If you are getting BadImageFormatException switch between x86 and x64 build settings.\n\nIn other cases, you might want to control the install location of the Python installation or even set it up yourself instead of having the Numpy library do it. For those cases Numpy.Bare is also great. Check out the [custom installation example](https://github.com/SciSharp/Numpy.NET/tree/master/src/Examples/CustomInstallLocationExample) if you want to know how.\n\n## How does it work?\n\nNumpy.NET uses [Python for .NET](http://pythonnet.github.io/) to call into the Python module `numpy`. However, this does not mean that it depends on a local Python installation! Numpy.NET.dll uses [Python.Included](https://github.com/henon/Python.Included) which packages embedded Python 3.7 and automatically deploys it in the user's home directory upon first execution. On subsequent runs, it will find Python already deployed and therefore doesn't install it again. Numpy.NET also packages the NumPy wheel and installs it into the embedded Python installation when not yet installed. \n\nLong story short: as a .NET Developer **you don't need to worry about Python** at all. You just reference Numpy.NET, use it and **it will just work**, no matter if you have local Python installations or not.\n\n## Multi-threading (Must read!)\n\n**Beware: Not following these steps can result in deadlocks or access violation exceptions!**\n\nPython/NumPy doesn't have real multi-threading support. There is no advantage in \"simultaneously\" executing `numpy` functions on multiple threads because `pythonnet` requires you to use the Global Interpreter Lock (GIL) to lock access to the Python engine exclusively for only one thread at a time. If you have to call Python from a thread other than the main thread you first must release the main thread's mutex by calling `PythonEngine.BeginAllowThreads()` or you'll have a deadlock: \n\n```csharp\nvar a = np.arange(1000);\nvar b = np.arange(1000);\n\n// https://github.com/pythonnet/pythonnet/issues/109\nPythonEngine.BeginAllowThreads();\n\nTask.Run(()=\u003e {\n  // when running on different threads you must lock!\n  using (Py.GIL())\n  {\n    np.matmul(a, b);\n  }\n}).Wait();\n```\nAbove example only serves as a reference on how to call `numpy` from a different thread than the main thread. As said before, having multiple background threads that call into Python doesn't give you multi-core processing because of the requirement to lock the GIL. Not doing so will result in **access violation exceptions** and/or **deadlocks**. \n\nNote that you must call a method of `np` before calling `PythonEngine.BeginAllowThreads()` in order for the PythonEngine to be initialized. So, for instance, if you want to initialize an inherently multi-threaded .Net Core Web API at startup, do something like this:\n\n```csharp\nnp.arange(1);\nPythonEngine.BeginAllowThreads();\n```\nAlso, if you do this, be sure to wrap any calls to Numpy in `using (Py.GIL()) { ... }` or else you'll get AccessViolationExceptions.\n\n## Performance considerations\n\nYou might ask how calling into Python affects performance. As always, it depends on your usage. Don't forget that `numpy`'s number crunching algorithms are written in `C` so the thin `pythonnet` and `Python` layers on top won't have a significant impact if you are working with larger amounts of data. \n\nIn my experience, calling `numpy` from C# is about 4 times slower than calling it directly in `Python` while the execution time of the called operation is of course equal. So if you have an algorithm that needs to call into `numpy` in a nested loop, Numpy.NET may not be for you due to the call overhead. \n\nAll of `numpy` is centered around the `ndarray` class which allows you to pass a huge chunk of data into the `C` routines and let them execute all kinds of operations on the elements efficiently without the need for looping over the data. So if you are manipulating arrays or matrices with thousands or hundreds of thousands of elements, the call overhead will be negligible. \n\nThe most performance sensitive aspect is creating an `NDarray` from a `C#` array, since the data has to be moved from the `CLR` into the `Python` interpreter. `pythonnet` does not optimize for passing large arrays from `C#` to `Python` but we still found a way to do that very efficiently. When creating an array with `np.array( ... )` we internally use `Marshal.Copy` to copy the entire `C#`-array's memory into the `numpy`-array's storage. And to efficiently retrieve computation results from `numpy` there is a method called `GetData\u003cT\u003e` which will copy the data back to `C#` in the same way:\n\n```csharp\n// create a 2D-shaped NDarray\u003cint\u003e from an int[]\nvar m = np.array(new int[] {1, 2, 3, 4});\n// calculate the cosine of each element\nvar result = np.cos(m);\n// get the floating point data of the result NDarray back to C#\nvar data = result.GetData\u003cdouble\u003e(); // double[] { 0.54030231, -0.41614684, -0.9899925 , -0.65364362 }\n```\n\n## Numpy.NET vs NumSharp\n\nThe SciSharp team is also developing a pure C# port of NumPy called [NumSharp](https://github.com/SciSharp/NumSharp) which is quite popular albeit being not quite complete.\n\nThere are a couple of other NumPy ports out there featuring subsets of the original library. The only one that matches Numpy.NET in terms of completeness is the IronPython package `numpy` which is out of date though. The SciSharp team is committed to keeping Numpy.NET up to date with the original library and to feature as much of the original functionality as possible.\n\n## Code generation\n\nThe vast majority of Numpy.NET's code is generated using [CodeMinion](https://github.com/SciSharp/CodeMinion) by parsing the documentation at [docs.scipy.org/doc/numpy/](docs.scipy.org/doc/numpy/). This allowed us to wrap most of the `numpy`-API in just two weeks. The rest of the API can be completed in a few more weeks, especially if there is popular demand. \n\n### Completion status\n\nThe following API categories have been generated (if checked off)\n - [x] Array creation routines \n - [x] Array manipulation routines\n - [x] Binary operations\n - [x] String operations\n - [x] Datetime Support Functions\n - [x] Data type routines\n - [x] Optionally Scipy-accelerated routines(numpy.dual)\n - [ ] Floating point error handling\n - [x] Discrete Fourier Transform(numpy.fft)\n - [x] Financial functions\n - [ ] Functional programming\n - [x] Indexing routines\n - [x] Input and output\n - [x] Linear algebra(numpy.linalg)\n - [x] Logic functions\n - [ ] Masked array operations\n - [x] Mathematical functions\n - [ ] Matrix library(numpy.matlib)\n - [ ] Miscellaneous routines\n - [x] Padding Arrays\n - [ ] Polynomials\n - [x] Random sampling(numpy.random)\n - [x] Set routines\n - [x] Sorting, searching, and counting\n - [x] Statistics\n - [x] Window functions\n \n Over 500 functions of all 1800 have been generated, most of the missing functions are duplicates on Matrix, Chararray, Record etc. \n\n### Auto-generated Unit-Tests\n\nWe even generated hundreds of unit tests from all the examples found on the NumPy documentation. Most of them don't compile without fixing them because we did not go so far as to employ a Python-To-C# converter. Instead, the tests are set up with a commented out Python-console log that shows what the expected results are and a commented out block of somewhat C#-ified Python code that doesn't compile without manual editing. \n\nAnother reason why this process can not be totally automated is the fact that NumPy obviously changed the way how arrays are printed out on the console after most of the examples where written (they removed extra spaces between the elements). This means that oftentimes the results needs to be reformatted manually for the test to pass.\n\nGetting more unit tests to run is very easy though, and a good portion have already been processed to show that Numpy.NET really works. If you are interested in working on the test suite, please join in and help. You'll learn a lot about NumPy on the way.\n\n## Documentation\n\nSince we have taken great care to make Numpy.NET as similar to NumPy itself, you can, for the most part, rely on the official [NumPy manual](https://docs.scipy.org/doc/numpy/). \n\n### Create a Numpy array from a C# array and vice versa\n\nTo work with data from C# in Numpy it has to be copied into the Python engine by using `np.array(...)`. You get an NDarray that you can use for further processing of the data. Here we calculate the square root:\n\n```csharp\n// create an NDarray from a C# array\nvar a = np.array(new[] { 2, 4, 9, 25 });\nConsole.WriteLine(\"a: \"+ a.repr);\n// a: array([ 2,  4,  9, 25])\n// apply the square root to each element\nvar roots = np.sqrt(a);\nConsole.WriteLine(roots.repr);\n// array([1.41421356, 2.        , 3.        , 5.        ])\n```\n\nAfter processing the data you can copy it back into a C# array use `a.GetData\u003cint\u003e()`, but be aware of the datatype of the NDarray in order to get correct values back:\n\n```csharp\n// Copy the NDarray roots into a C# array from NDarray (incorrect datatype)\nConsole.WriteLine(string.Join(\", \", roots.GetData\u003cint\u003e()));\n// 1719614413, 1073127582, 0, 1073741824 \nConsole.WriteLine(\"roots.dtype: \" + roots.dtype);\n// roots.dtype: float64\nConsole.WriteLine(string.Join(\", \", roots.GetData\u003cdouble\u003e()));\n// 1.4142135623731, 2, 3, 5\n```\n\n### Creating multi-dimensional NDarrays from C# arrays\n\nCreating an `NDarray` from data is easy. Just pass the C# array into `np.array(...)`. You can pass 1D, 2D and 3D C# arrays into it. \n\n```csharp\n// create a 2D NDarray\nvar m = np.array(new int[,] {{1, 2}, {3, 4}}); // the NDarray represents a 2 by 2 matrix\n```\n\nAnother even more efficient way (saves one array copy operation) is to pass the data as a one-dimensional array and just reshape the NDarray. \n\n```csharp\n// create a 2D NDarray\nvar m = np.array(new int[] {1, 2, 3, 4}).reshape(2,2); // the reshaped NDarray represents a 2 by 2 matrix\n```\n\n### Differences between Numpy.NET and NumPy\n\nAs you have seen, apart from language syntax and idioms, usage of Numpy.NET is almost identical to Python. However, due to lack of language support in C#, there are some differences which you should be aware of.\n\n#### Array slicing syntax\nYou can access parts of an NDarray using [array slicing](https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#arrays-indexing). C# doesn't support the colon syntax in indexers i.e. `a[:, 1]`. However, by allowing to pass a string we circumvented this limitation, i.e. `a[\":, 1\"]`. Only the `...` operator is not yet implemented, as it is not very important. \n\n#### Variable argument lists\nSome NumPy functions like `reshape` allow variable argument lists at the beginning of the parameter list. This of course is not allowed in C#, which supports a variable argument list only as the last parameter. In case of `reshape` the solution was to replace the variable argument list that specifies the dimensions of the reshaped array by a `Shape` object which takes a variable list of dimensions in its constructor: \n\n```csharp\nvar a=np.arange(24);\nvar b=np.reshape(a, new Shape(2, 3, 4)); // or a.reshape(2, 3, 4)\n```\n\nIn other cases the problem was solved by providing overloads without the optional named parameters after the variable argument list. \n\n#### Parameter default values\n\nC# is very strict about parameter default values which must be compile time constants. Also, parameters with default values must be at the end of the parameter list. The former problem is usually solved by having a default value of `null` instead of the non-compile-time constant and setting the correct default value inside the method body when called with a value of `null`. \n\n#### Unrepresentable operators\nPython operators that are not supported in C# are exposed as instance methods of `NDarray`:\n\n| Python | C# |\n| ------ | ------ |\n| //     | floordiv() |\n| **     | pow() |\n\n\n#### Inplace modification\nIn NumPy you can write `a*=2` which doubles each element of array `a`. C# doesn't have a `*=` operator and consequently overloading it in a Python fashion is not possible. This limitation is overcome by exposing inplace operator functions which all start with an 'i'. So duplicating all elements of array `a` is written like this in C#: `a.imul(2);`. The following table lists all inplace operators and their pendant in C#\n\n| Python | C# |\n| ------ | ------ |\n| +=     | iadd() |\n| -=     | isub() |\n| \\*=    | imul() |\n| /=     | idiv() or itruediv() |\n| //=    | ifloordiv() |\n| %=     | imod() |\n| \\*\\*=  | ipow() |\n| \u003c\u003c=    | ilshift() |\n| \u003e\u003e=    | irshift() |\n| \u0026=     | iand() |\n| \\|=    | ior() |\n| ^=     | ixor() |\n\n#### (Possible) scalar return types\nIn NumPy a function like `np.sqrt(a)` can either return a scalar or an array, depending on the value passed into it. In C# we are trying to solve this by creating overloads for every scalar type in addition to the original function that takes an array and returns an array. This bloats the API however and hasn't been done for most functions and for some it isn't possible at all due to language limitations. The alternative is to cast value types to an array (NDarray can represent scalars too):\n\nSo a simple `root = np.sqrt(2)` needs to be written somewhat clumsily like this in C#: `var root = (double)np.sqrt((NDarray)2.0);` until overloads for every value type are added in time for your convenience. In any case, the main use case for NumPy functions is to operate on the elements of arrays, which is convenient enough:\n\n```csharp\nvar a = np.arange(100); // =\u003e { 0, 1, 2, ... , 98, 99 }\nvar roots = np.sqrt(a); // =\u003e { 0.0, 1.0, 1.414, ..., 9.899, 9.950 }\n```\n\n#### Complex numbers\nNumpy.NET supports complex numbers even though the notation in Python and C# is very different:\n```python\n\u003e\u003e\u003e a = np.array([1+2j, 3+4j, 5+6j])\n```\nlooks like this in C#\n```c#\nvar a = np.array(new Complex[] { new Complex(1, 2), new Complex(3,4), new Complex(5,6), });\n```\nAccess the real and imaginary components of a complex array via `a.real` and `a.imag` or copy the complex values of an ndarray into C# with `Complex[] c=a.GetData\u003cComplex\u003e();`.\n\n#### Functions clashing with their class name\nThe function fft(...) in numpy.fft and random(...) in numpy.random had to be renamed because C#  doesn't allow a member to have the same name as its enclosing class. That's why in Numpy.NET these functions have been renamed with a trailing underscore like this: `np.fft.fft_(...)`\n\n## Versions and Compatibility\n\nCurrently, Numpy.dll is targeting .NET Standard (on Windows) and packages the following binaries:\n* Python 3.7: (python-3.7.3-embed-amd64.zip)\n* NumPy 1.16 (numpy-1.16.3-cp37-cp37m-win_amd64.whl)\n\nNumpy.Bare.dll is available for the Python versions 2.7, 3.5, 3.6 and 3.7 on Windows, Linux and MacOS on Nuget.\n\nTo make Numpy.dll support Linux a separate version of [Python.Included](https://github.com/henon/Python.Included) packaging linux binaries of Python needs to be made and a version of Numpy.dll that packages a linux-compatible NumPy wheel. If you are interested, you may work on this issue. \n\n## License\n\nNumpy.NET packages and distributes `Python`, `pythonnet` as well as `numpy`. All these dependencies imprint their license conditions upon Numpy.NET. The C# wrapper itself is MIT License. \n\n* Python: [PSF License](https://docs.python.org/3/license.html)\n* Python for .NET (pythonnet): [MIT License](http://pythonnet.github.io/LICENSE)\n* NumPy: [BSD License](https://www.numpy.org/license.html#license)\n* Numpy.NET: [MIT License](./LICENSE)\n\n## Common Mistakes\n* If you check `Prefer 32-bit` in your build config or build with `x86` instead of `Any CPU` Numpy.NET will crash with `BadFormatException`\n* If you have insufficient folder permissions in AppData Numpy.NET might crash. You can specify a different installpath by setting `Installer.INSTALL_PATH = \"\u003cinstall path\u003e\";`\n* If you get deadlocks (program hangs indefinitely) you should read the secton about multi-threading above!\n* If you get AccessViolationExceptions you should read the secton about multi-threading above!\n\n## Project Sponsors\n* [JetBrains](https://www.jetbrains.com/?from=Numpy.NET)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscisharp%2Fnumpy.net","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscisharp%2Fnumpy.net","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscisharp%2Fnumpy.net/lists"}