Reputation: 43039
I have this code:
import numpy as np
data = np.zeros((len(file_dirs),4097))
for i in range(len(file_dirs)):
data[i][:] = np.loadtxt(file_dirs[i])
The loop seems to produce the same result with this as well:
for i in range(len(file_dirs)):
data[i] = np.loadtxt(file_dirs[i])
What is the difference between data[i]
and data[i][:]
on the LHS?
Upvotes: 1
Views: 66
Reputation: 96172
Slicing and indexing numpy.ndarray
objects produces a view over the same underlying, primitive buffer. They are different Python objects sharing the same buffer. data[i]
produces a new numpy.ndarray object, that is sliced with a full slice, which simply returns another object with a view over the same exact data, which was a view of the original. The item-assignment operator, container[item] = value
, works in-place (as it does with built-in containers as well, like list
and dict
),
data[i][:] = np.loadtxt(file_dirs[i])
so that same buffer is modified. Hence, that acts equivalently to:
data[i] = np.loadtxt(file_dirs[i])
But note, this would not work the same way with Python list
objects (and most other mutable objects you'll encounter in Python). A slice of a list produces a new object as well, but it is independent of the original without sharing memory.
>>> mylist = list(range(10))
>>> middle_six = mylist[2:-2]
>>> mylist
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> middle_six
[2, 3, 4, 5, 6, 7]
>>> middle_six[:] = [ -133, 212, 88, 23, 650, -88]
>>> mylist
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> middle_six
[-133, 212, 88, 23, 650, -88]
And now note what happens with numpy
arrays:
>>> import numpy as np
>>> arr = np.arange(10)
>>> middle_six = arr[2:-2]
>>> arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> middle_six
array([2, 3, 4, 5, 6, 7])
>>> middle_six[:] = [98, 101, -88, 17, 525, 88]
>>> middle_six
array([ 98, 101, -88, 17, 525, 88])
>>> arr
array([ 0, 1, 98, 101, -88, 17, 525, 88, 8, 9])
Note, only some operations in numpy produce a view. "Fancy indexing", for example, with a sequence of indices, does not produce a view:
>>> arr = np.arange(10)
>>> first_three = arr[[0,1,2]]
>>> arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> first_three
array([0, 1, 2])
>>> first_three[:] = [42, 42, 42]
>>> arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> first_three
array([42, 42, 42])
>>>
Upvotes: 2