Как указано на:
101 Образцы LINQ - левое внешнее соединение
var q =
from c in categories
join p in products on c.Category equals p.Category into ps
from p in ps.DefaultIfEmpty()
select new { Category = c, ProductName = p == null ? "(No products)" : p.ProductName };
NumPy's arrays are more compact than Python lists -- a list of lists as you describe, in Python, would take at least 20 MB or so, while a NumPy 3D array with single-precision floats in the cells would fit in 4 MB. Access in reading and writing items is also faster with NumPy.
Maybe you don't care that much for just a million cells, but you definitely would for a billion cells -- neither approach would fit in a 32-bit architecture, but with 64-bit builds NumPy would get away with 4 GB or so, Python alone would need at least about 12 GB (lots of pointers which double in size) -- a much costlier piece of hardware!
The difference is mostly due to "indirectness" -- a Python list is an array of pointers to Python objects, at least 4 bytes per pointer plus 16 bytes for even the smallest Python object (4 for type pointer, 4 for reference count, 4 for value -- and the memory allocators rounds up to 16). A NumPy array is an array of uniform values -- single-precision numbers takes 4 bytes each, double-precision ones, 8 bytes. Less flexible, but you pay substantially for the flexibility of standard Python lists!
Алекс упомянул об эффективности памяти, а Роберто упомянул удобство, и это оба хорошие моменты. В качестве дополнительных идей я упомяну скорость и функциональность .
Функциональность: Вы получаете много встроенных функций с помощью NumPy, БПФ, сверток, быстрого поиска, базовой статистики, линейная алгебра, гистограммы и т. д. И действительно, кто может жить без БПФ?
Скорость: Вот тест по вычислению суммы по списку и массиву NumPy, показывающий, что сумма в массиве NumPy в 10 раз быстрее (в этом тест - пробег может отличаться).
from numpy import arange
from timeit import Timer
Nelements = 10000
Ntimeits = 10000
x = arange(Nelements)
y = range(Nelements)
t_numpy = Timer("x.sum()", "from __main__ import x")
t_list = Timer("sum(y)", "from __main__ import y")
print("numpy: %.3e" % (t_numpy.timeit(Ntimeits)/Ntimeits,))
print("list: %.3e" % (t_list.timeit(Ntimeits)/Ntimeits,))
который в моих системах (пока я выполняю резервное копирование) дает:
numpy: 3.004e-05
list: 5.363e-04
NumPy не просто более эффективен; это тоже удобнее. Вы получаете бесплатно множество векторных и матричных операций, которые иногда позволяют избежать ненужной работы. И они также эффективно реализованы.
Например, вы можете прочитать свой куб прямо из файла в массив:
x = numpy.fromfile(file=open("data"), dtype=float).reshape((100, 100, 100))
Суммировать по второму измерению:
s = x.sum(axis=1)
Найти, какие ячейки находятся выше порогового значения:
(x > 0.5).nonzero()
Удалить каждый срез с четным индексом по третьему измерению:
x[:, :, ::2]
Кроме того, многие полезные библиотеки работают с массивами NumPy. Например, библиотеки статистического анализа и визуализации.
Даже если у вас нет проблем с производительностью, изучение NumPy того стоит.