NumPy - В чем разница между буфером и строкой?

Кажется, они дают мне тот же результат:

In [32]: s
Out[32]: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

In [27]: np.frombuffer(s, dtype="int8")
Out[27]:
array([ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0, 21,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0], dtype=int8)

In [28]: np.fromstring(s, dtype="int8")
Out[28]:
array([ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0, 21,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0], dtype=int8)

In [33]: b = buffer(s)

In [34]: b
Out[34]: <read-only buffer for 0x035F8020, size -1, offset 0 at 0x036F13A0>

In [35]: np.fromstring(b, dtype="int8")
Out[35]:
array([ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0, 21,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0], dtype=int8)

In [36]: np.frombuffer(b, dtype="int8")
Out[36]:
array([ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0, 21,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0], dtype=int8)

Когда нужно использовать против другого?

Ответ 1

С практической точки зрения разница заключается в том, что:

x = np.fromstring(s, dtype='int8')

Выполним копию строки в памяти, а:

x = np.frombuffer(s, dtype='int8')

или

x = np.frombuffer(buffer(s), dtype='int8')

Будет использовать буфер памяти строки напрямую и не будет использовать никакой дополнительной памяти. Использование frombuffer также приведет к массиву только для чтения, если вход в buffer является строкой, поскольку строки являются неизменяемыми в python.

(* Пренебрежение несколькими байтами памяти, используемыми для дополнительного объекта python ndarray. Базовая память для данных будет разделяться.)


Если вы не знакомы с buffer объектами (memoryview в python3.x), они по сути являются способом для библиотек уровня C выставить блок памяти для использования в python. Это в основном интерфейс python для управляемого доступа к необработанной памяти.

Если вы работали над тем, что отображало интерфейс буфера, то вы, вероятно, захотите использовать frombuffer. (Строки Python 2.x и python 3.x bytes выставляют интерфейс буфера, но вы получите массив только для чтения, поскольку строки python неизменяемы.)

В противном случае используйте fromstring для создания массива numpy из строки. (Если вы не знаете, что делаете, и хотите жестко контролировать использование памяти и т.д.)