I've been working in Python with an array which contains a one-dimensional list of values. I have until now been using the array.append(value) function to add values to the array one at a time.
Now, I would like to add all the values from another array to the main array instead. In other words I don't want to add single values one at a time. The secondary array collects ten values, and when these are collected, they are all transfered to the main array. The problem is, I can't simply use the code 'array.append(other_array)', as I get the following error:
unsupported operand type(s) for +: 'int' and 'list'
Where am I going wrong?
Lists can be added together:
>>> a = [1,2,3,4]
>>> b = [5,6,7,8]
>>> a+b
[1, 2, 3, 4, 5, 6, 7, 8]
and one can be easily added to the end of another:
>>> a += b
>>> a
[1, 2, 3, 4, 5, 6, 7, 8]
You are looking for array.extend() method. append() only appends a single element to the array.
Array (as in numpy.array or array module) or list? Because given your error message, it seems the later.
Anyway, you can use the += operator, that should be overridden for most container types, but the operands must be of the same (compound) type.
Usually, if you want to expand a structure to the right (axis=1) or at the bottom (axis=0), you should have a look at the numpy.concatenate() function, see Concatenate a NumPy array to another NumPy array.
np.concatenate(arr1, arr2, axis=0)
is probably what is needed here, adding a new row in a nested array.
Related
Let's say we have a simple 1D ndarray. That is:
import numpy as np
a = np.array([1,2,3,4,5,6,7,8,9,10])
I want to get the first 3 and the last 2 values, so that the output would be [ 1 2 3 9 10].
I have already solved this by merging and concatenating the merged variables as follows :
b= a[:2]
c= a[-2:]
a=np.concatenate([b,c])
However I would like to know if there is a more direct way to achieve this using slices, such as a[:2 and -2:] for instance. As an alternative I already tried this :
a = a[np.r_[:2, -2:]]
but it not seems to be working. It returns me only the first 2 values that is [1 2] ..
Thanks in advance!
Slicing a numpy array needs to be continuous AFAIK. The np.r_[-2:] does not work because it does not know how big the array a is. You could do np.r_[:2, len(a)-2:len(a)], but this will still copy the data since you are indexing with another array.
If you want to avoid copying data or doing any concatenation operation you could use np.lib.stride_tricks.as_strided:
ds = a.dtype.itemsize
np.lib.stride_tricks.as_strided(a, shape=(2,2), strides=(ds * 8, ds)).ravel()
Output:
array([ 1, 2, 9, 10])
But since you want the first 3 and last 2 values the stride for accessing the elements will not be equal. This is a bit trickier, but I suppose you could do:
np.lib.stride_tricks.as_strided(a, shape=(2,3), strides=(ds * 8, ds)).ravel()[:-1]
Output:
array([ 1, 2, 3, 9, 10])
Although, this is a potential dangerous operation because the last element is reading outside the allocated memory.
In afterthought, I cannot find out a way do this operation without copying the data somehow. The numpy ravel in the code snippets above is forced to make a copy of the data. If you can live with using the shapes (2,2) or (2,3) it might work in some cases, but you will only have reading permission to a strided view and this should be enforced by setting the keyword writeable=False.
You could try to access the elements with a list of indices.
import numpy as np
a = np.array([1,2,3,4,5,6,7,8,9,10])
b = a[[0,1,2,8,9]] # b should now be array([ 1, 2, 3, 9, 10])
Obviously, if your array is too long, you would not want to type out all the indices.
Thus, you could build the inner index list from for loops.
Something like that:
index_list = [i for i in range(3)] + [i for i in range(8, 10)]
b = a[index_list] # b should now be array([ 1, 2, 3, 9, 10])
Therefore, as long as you know where your desired elements are, you can access them individually.
I have an xarray of shape [3,] that looks like this
data= [2,4,6]
and I'm trying to copy it into array so that it looks like this:
data= [[2,4,6],[2,4,6],[2,4,6]]
(ie the entire array is copied three times).
I've tried a few different methods but keep getting:
data= [2 2 2,4 4 4,6 6 6]
Anyone know how I should go about doing this? (Also, sorry if I wrote this not according to the stack overflow rules, this is my first question...)
The first two answers don't actually copy the original array/list. Rather, they both just reference the array three times inside a new list. If you change one of the values inside of the the original array or any of the "copies" inside the new list, all of the "copies" of the array will change because they're really all the same structure just referenced in multiple places.
If you want to create a list containing three unique copies of your original array (xarray or list), you can do this:
new_list = [data[:] for _ in range(3)]
or if you want a new xarray containing your original array:
new_array = xarray.DataArray([data[:] for _ in range(3)])
I think the safest approach would be this:
import itertools
data = [2,4,6]
res = list(itertools.chain.from_iterable(itertools.repeat(x, 3) for x in [data]))
print(res)
Output: [[2, 4, 6], [2, 4, 6], [2, 4, 6]]
I have an array of float values which I then pass to an equation to produce a corresponding array. However, I would like to keep the first n values of this array constant, and then all values after that to be passed to the equation.
What is this best way to do this in Python?
Just slice the array to pass the values after the nth to your "equation" (which I assume is a function?).
def equation(l):
return sum(l) # for example
a = [1, 2, 3, 4, 5, 6, 7, 8]
n = 4
>>> equation(a[n:])
26
>>> equation(a[3:6])
15
This passes only those values after the fourth in list a. Actually it passes a copy of that part of the list after the fourth, so your function is free to change the values therein without side effects.
I've looked into the many posts about getting every nth item of an array, and I used the method for slicing even and odd indices. However, I end up with an empty array for the final object. Any suggestions?
floc1 is an array, and I want to subtract every odd element from every even element:
period = abs(floc1[0::2] - floc1[1::2])
This currently gives me an empty array.
EDIT:
I've tried everything suggested in the comments below. The only thing that generated a different error was:
period = [i-j for i, j in zip(floc1[0::2], floc1[1::2])]
This gives:
Phi12 = ((tau)/(period))
ValueError: operands could not be broadcast together with shapes (1,8208) (0,)
In reference to:
Phi12 = ((tau)/(period))
Again, floc1 is definitely not an empty array. I saved it to a text file to confirm.
Your example gives an error if floc1 is a list (which people often call an "array"). For a list you can do it this way.
>>> floc1 = [11, 5, 6, 2]
>>> it = iter(floc1)
>>> [x - next(it) for x in it]
[6, 4]
You can also use zip if you prefer see #wenzul's answer
If floc1 is a numpy.array - what you have already works
>>> import numpy as np
>>> floc1 = np.array([11, 5, 6, 2])
>>> abs(floc1[0::2] - floc1[1::2])
array([6, 4])
Perhaps your floc1 is actually an empty array
It's not working because you try to substract a list from a list.
You need to do that element-wise.
>>> for i, k in zip(floc1[0::2], floc1[1::2]):
... print abs(i-k)
Also look into this.
Let's say I have an array
a = np.array[5, 3, 2]
and based on that array I want to return a new array in the form:
b = np.array[ [0, 1, 2, 3, 4], [0, 1, 2], [0, 1] ]
I've been trying:
for item in a:
b = np.hstack(np.arange(item))
print b
but this only gives me the elements without joining them into an array;
for item in a:
b = b.append((b[:], b[item]))
print b
but this approach blows up nicely with a:
AttributeError: 'numpy.ndarray' object has no attribute 'append'
I have tried other things, like:
b[item] = np.arange(item),
but that one complains about out-of-bounds indices.
And
b = np.zeros(len(a))
for item in np.arange(len(a)):
b[item] = np.arange(b[item])
print b
which complains with
ValueError: setting an array element with a sequence.
That last one is the one that looks more promising and, searching for some questions on this site (https://stackoverflow.com/a/13311979/531687) I know that the problem is that I am trying to fit a sequence where a value is expected, but I can't figure out my way around it.
How can I go about this?
This should work
b = [range(x) for x in a]
update
The brackets [...] here create a list and inside an iterator can be used to define the items in the list. In this case the items of of type range(x) for each item in a.
Note that there is a difference in implementation between python2 and python3 here. In python2 this actually generates a list of lists. In python3 however this generates a lists of generators (the python2 equivalent would be xrange), which is typically more efficient.