I'm trying to insert one array into another, but I think I'm having a dimensioning issue with the arrays, leading to a ValueError. The exponential segment I'm trying to insert lives in EXP and prints as I'd expect, but running len() on it returns 1. Why would an array that prints with more than one element return a len() of 1? Code snippet below:
SPR = 48000 # Hz
duration = 0.2 # second
t = numpy.linspace(0, duration, duration * SPR)
p_list = [0, numpy.pi, 0]
SIGNALS = [(16000 * numpy.sin((2 * numpy.pi * t * 20) + p)).astype('int16')
for p in p_list]
EXP = [(16000 * (2**(-100*t))).astype('int16')]
e=EXP[0:4200]
print(e)
print(len(e))
SIGNALS[0][600:4800] = e
returns
[array([16000, 15976, 15953, ..., 0, 0, 0], dtype=int16)]
1
Traceback (most recent call last):
File "/home/pi/Experiments/actronika-exp.py", line 87, in <module>
SIGNALS[0][600:4800] = e
ValueError: setting an array element with a sequence.
The problem is that you are inserting the array inside a list when you do:
X = [np.array([0, ...])]
Thus X is a list with a array inside, I think you should just do:
X = np.array([0, ...])
However, if you need the array inside list thing, you should change this line
e=EXP[0:4200]
to
e=EXP[0][0:4200]
Now you are taking the first array, inside the list EXP.
[array([16000, 15976, 15953, ..., 0, 0, 0], dtype=int16)]
This (e) is a numpy array inside a python list. len(e) returns the list's length, which is 1, since it contains 1 element: the numpy array
Related
I'm new to Numpy. I have the following variables:
import numpy as np
arr = np.array([[3, 5, 9], [1, 2, 3]]).T
Dr = 2
Dl = 3
Db = 4
delta_R = arr[0, 0]
delta_L = arr[1, 0]
delta_B = arr[2, 0]
delta_theta = (delta_L - delta_R) / (Dr + Dl)
I'm attempting to implement the following equation:
To do so, I've written:
delta_x_delta_y_arr = np.array([2*np.sin(delta_theta/2) * np.array([(delta_B / delta_theta) + Db], [(delta_R / delta_theta) + Dr])])
Firstly, I'm not certain whether I've expressed this equation properly using Numpy arrays. If I have, why do I see the following traceback?
TypeError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_5072/2142976421.py in <module>
----> 1 delta_x_delta_y_arr = np.array([2*np.sin(delta_theta/2) * np.array([(delta_B / delta_theta) + Db], [(delta_R / delta_theta) + Dr])])
TypeError: Field elements must be 2- or 3-tuples, got '9.5'
Thanks in advance for any assistance you can give this Numpy newbie!
The NumPy array should be np.array([[...], [...]]) rather than np.array([...], [...]). Try
delta_x_delta_y_arr = 2*np.sin(delta_theta/2) * np.array([[(delta_B / delta_theta) + Db], [(delta_R / delta_theta) + Dr]])
instead.
Your np.array argument is too long to readily read - and write correctly. Extracted, and edited for clarity:
np.array([2*np.sin(delta_theta/2) *
np.array([(delta_B / delta_theta) + Db],
[(delta_R / delta_theta) + Dr])
]
The inner array has 2 list arguments. https://stackoverflow.com/a/72905294/901925 is right in saying that it is wrong. Here's why:
The signature for np.array is:
array(object, dtype=None, ...)
So it's trying to interpret the 2nd list as a dtype. A typical compound dtype looks like:
[('f0',int), ('f1',float,3)]
In other words, if the dtype is a list, it expects tuples, with 2 or 3 elements.
Field elements must be 2- or 3-tuples, got '9.5'
I haven't seen this error before, but based on what I know about making structured arrays, this makes sense. In cases like this, it's a good idea to double check your arguments against the function documentation.
And avoid overly long lines.
I have a simple for loop to calculate RMS(root mean square) which is defined in sigma summation form:
for i in range(int(N-(n*periyot/delta)), N+1):
sum = np.sqrt((1 / N) * (sum((Cl[i]**2))))
Then I got this error:
TypeError: 'numpy.float64' object is not iterable
Here are some information about my definitons:
N=40000, n=10.0, periyot=6.451290, delta=0.005
Cl=[-21.91969 -12.452671 -7.928303 ..., -0.0833991 -0.0579686
-0.0823822]
Remove that sum, each element of Cl is a float so you can't possibly call sum on them:
>>> sum(2.4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'float' object is not iterable
If you intend to invoke numpy's broadcasting to perform the power operation then you don't need to index the array.
The problem is that you overwrite sum function with sum variable. Try something like this:
my_sum = 0
for i in range(int(N-(n*periyot/delta)), N+1):
my_sum += np.sqrt((1 / N) * (sum((Cl[i]**2))))
Replicating your calculation, a bit simplified:
In [1]: Cl = np.array([-21.91969 , -12.452671 , -7.928303 , -0.0833991,-0.0579686,-0.0823822])
To calculate a sum in a loop, initial a value, and add to it at each iteration:
In [2]: res = 0
In [3]: for i in range(len(Cl)):
...: res += np.sqrt((1/3)*Cl[i]**2)
...:
In [4]: res
Out[4]: 24.551481812296061
Letting numpy calculate everything (slightly different)
In [5]: np.sqrt((1/3)*Cl**2).sum()
Out[5]: 24.551481812296064
Your range is a little more complicated, but I think that can be accommodated with:
s, e = int(N-(n*periyot/delta)), N+1 # start, end of range
for i in range(s, e): ....
or
np.sqrt((1/N) * Cl[s:e]**2).sum()
But I wonder why you started with that sum((Cl[i]**2))). Where you hoping to square a range of Cl values and then sum them? And repeat that for multiple ranges?
=============
There's a np.sum and a Python sum. Python sum works nicely with a list of numbers, such as those generated by a list comprehension:
In [6]: [np.sqrt((1/3)*Cl[i]**2) for i in range(len(Cl))]
Out[6]:
[12.655338922053147,
7.1895529539798462,
4.5774078712669173,
0.048150492835172518,
0.03346818681454574,
0.047563385346433583]
In [7]: sum([np.sqrt((1/3)*Cl[i]**2) for i in range(len(Cl))])
Out[7]: 24.551481812296061
The errors that result from trying to apply sum to a single value:
In [9]: sum(Cl[0])
....
TypeError: 'numpy.float64' object is not iterable
In [10]: sum(12.234)
...
TypeError: 'float' object is not iterable
In [11]: sum(Cl[:3]) # sum of several items
Out[11]: -42.300663999999998
==========
RMS = ( (1 / N ) * (Cl[1]^2 + Cl[2]^2 + Cl[3]^2 + ... Cl[N]^2) ) ^0.5
is expressed, for lists as:
rms = (1/n) * math.sqrt(sum([Cl[1]**2, Cl[2]**2, ....]))
rms = (1/n) * math.sqrt(sum([Cl[i]**2 for i in range(len(Cl))]))
rms = (1/n) * math.sqrt(sum([c**2 for c in Cl])) # iterate on Cl directly
rms = (1/n) * np.sqrt(np.sum(Cl**2)) # for array Cl
I am having a problem with calling a function twice. If I comment my last 3 lines and keep show(), I don't get any errors and things come as they are suppose to. However, if I don't comment them out calling the last function again gives me this error:
Traceback (most recent call last):
File "second_1.py", line 29, in <module>
domega=c_d(len(t),t,z)
File "second_1.py", line 25, in c_d
dy[1:-1]=(y[2:]-y[0:-2])/(x[2:]-x[0:-2])
TypeError: unsupported operand type(s) for -: 'list' and 'list'
Here is the function:
import numpy as np
from pylab import *
import time
t_initial=time.time()
clf()
t,hp,hn= np.loadtxt("Richardson.dat", usecols=(0,1,2),comments='#', unpack=True) # to select just a few columns
print(time.time()-t_initial)
def phi(y,x):
return(np.arctan(y/x))
phase=[0.0]*len(t)
phase=phi(hp[0:],hn[0:])
#plot(t,phase)
#show()
def c_d(order,x,y):
dy=[0.0]*order
dy[0]=(y[1]-y[0])/(x[1]-x[0])
dy[-1]=(y[-1]-y[-2])/(x[-1]-x[-2])
dy[1:-1]=(y[2:]-y[0:-2])/(x[2:]-x[0:-2])
return(dy);
z=c_d(len(t),t,phase);
plot(t,z)
print(len(z)-len(t))
domega=c_d(len(t),t,z)
plot(t,domega)
show()
The problem is very clearly explained in the error message:
The '-' operand is not applicable for the type list.
(y[2:]-y[0:-2])/(x[2:]-x[0:-2])
y[2:] slices a list and returns a list. y[0:-2] slices also a list and returns a list. So there you have 2 lists.
y[2:] (a list) -(your operator) y[0:-2] (a list)
And list - list is not defined (there is no syntax for: 'listObject' - 'listObject').
BUT: the + operator is defined for lists (example):
l = ["ja"]
m = ["nein"]
n = l + m
print n
# output: ['ja', 'nein']
Take a look here for these different kind of possible operators:
https://docs.python.org/2/library/stdtypes.html
As explained in the other answers, you can not subtract regular Python lists. So why does it work the first time, and fails the second? Let's take a look at the code.
t, hp, hn = np.loadtxt(...)
...
def c_d(order, x, y):
dy = [0.0] * order
dy[ 0] = (y[1] -y[0]) / (x[ 1]-x[0])
dy[-1] = (y[-1]-y[-2]) / (x[-1]-x[-2])
dy[1:-1] = (y[2:]-y[0:-2]) / (x[2:]-x[0:-2])
return dy
z = c_d(len(t), t, phase)
...
domega = c_d(len(t), t, z)
...
When you first call c_d, the parameters x and y seem to be numpy arrays (at least t and phase are results of numpy function calls), and for those, - is a legal operation. But inside c_d, you create and finally return a regular Python list, dy, so when you then call c_d again with the result of the first call as y, this part y[2:]-y[0:-2] will fail, as y now is a regular list.
Make sure your dy is a numpy array, too, i.e. dy = np.array([0.0] *order) or just dy = np.zeros(order), then it should work.
As stated by Cyber and ProgrammingIsAwsome the error is on line
(y[2:]-y[0:-2])/(x[2:]-x[0:-2])
where you actually try to substract lists.
You could write explicitely :
for i in range(1, order - 1):
dy[i]=(y[i+1]-y[i-1])/(x[i+1]-x[1-1])
Following to this post:
How to put complex into a numpy's array?
It seems work well for me.
But why did i get this error in this case?
1 #!/usr/bin/env python
2 import scipy.special
3 import numpy as np
4
5 deg = 10
6 nodes = np.polynomial.legendre.leggauss(deg)[0]
7 A = np.zeros((deg, deg), dtype=complex)
8 for i in range(0, deg):
9 for j in range(0, deg):
10 A[i, j] = scipy.special.sph_yn(0, nodes[i]*nodes[j])[0]
machine:Desktop users$ ./aa.py
Traceback (most recent call last):
File "./aa.py", line 10, in <module>
A[i, j] = scipy.special.sph_yn(0, nodes[i]*nodes[j])[0]
TypeError: can't convert complex to float
Additional: What did i get from sph_yn if i comment line 10 and print scipy.special.sph_yn(0, nodes[i]*nodes[j])[0] out in nest for loop
[-0.61456112]
[-0.79004531]
[-1.19235662]
[-2.16125343]
[-6.82467416]
[ 6.82467416+0.j]
[ 2.16125343+0.j]
[ 1.19235662+0.j]
[ 0.79004531+0.j]
[ 0.61456112+0.j]
... and so on
special.sph_yn(0, nodes[i]*nodes[j])[0] returns a numpy array containing 1 element. You want to assign the value inside this array to A, not the array itself. To get the single value out of the array, use the item() method:
A[i, j] = special.sph_yn(0, nodes[i]*nodes[j])[0].item()
Note that using a list comprehension:
A = np.array([[special.sph_yn(0, nodes[i]*nodes[j])[0].item()
for j in range(deg)]
for i in range(deg) ])
would also work, and (if you have the memory) is faster than assigning values to a NumPy array one element at a time.
I want to read a .tif file and count the number of pixels in an image and determine the density of objects, but when I attempt this y, x = np.indices(image.shape) it gives me then
Value Error (ValueError: too many values to unpack, File "<stdin>", line 1, in <module>).
My code is as follows:
import sys
import os
import numpy as np
from pylab import *
import scipy
import matplotlib.pyplot as plt
import math
#Function
def radial_plot(image):
y, x = np.indices(image.shape) # <----- Problem here???
center = np.array([(x.max()-x.min())/2.0, (x.max()-x.min())/2.0])
r = np.hypot(x - center[0], y - center[1])
ind = np.argsort(r.flat)- center[1])
r_sorted = r.flat[ind]
i_sorted = image.flat[ind]
r_int = r_sorted.astype(int)
deltar = r_int[1:] - r_int[:-1]
rind = np.where(deltar)[0]
nr = rind[1:] - rind[:-1]
csim = np.cumsum(i_sorted, dtype=float)
tbin = csim[rind[1:]] - csim[rind[:-1]]
radial_prof = tbin / nr
return rad
#Main
img = plt.imread('dat.tif')
radial_plot(img)
The issue is that you are attempting to assign more than two values to only two varibles:
>>> a, b = range(2) #Assign two values to two variables
>>> a
0
>>> b
1
>>> a, b = range(3) #Attempt to assign three values to two variables
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack
In Python 2.x you can do the following:
>>> a, b = range(3)[0], range(3)[1:]
>>> a
0
>>> b
[1, 2]
Just for completeness, if you had Python 3.x, you could do Extended Iterable Unpacking:
>>> a, *b, c = range(5)
>>> a
0
>>> c
4
>>> b
[1, 2, 3]
Hope this helps
np.indices returns an array representing the indices of the grid. The error basically indicates that there are more than 2 values obtained by calling the indices method. Since it's returning a grid, you can assign it to a variable such as grid and then access the indices accordingly.
The crux of the error is the function call returns more than just 2 values, and in your code you are trying to 'squeeze' them into just 2 variables.
For eg.
s = "this is a random string"
x, y = s.split()
The above code gives you a value error since there are 5 strings obtained by calling split(), while I am trying to accommodate them into just 2 variables.