IndexError: invalid index to scalar variable in for loop - python

I have an array of array's named pdf of len(pdf) = 300
pdf[0] is an array of len(pdf[0]) = 300
What I would like to do is, take the sum of pdf[0][50:100] and repeat the same for pdf[1][50:100] and so on upto pdf[300][50:100].
What I tried is:
for i,a in enumerate(pdf):
result.append(a[i][50:100].sum())
But I get the error:
IndexError: invalid index to scalar variable

If you just need to build a simple list, then a List Comprehension is your friend:
result = [i[50:100].sum() for i in pdf]
Should do it.
In your for loop,
a is pdf[0], pdf[1]...
i is 0,1...
so you are referencing pdf[0][0][50:100], pdf[1][1][50:100]... hence the tracebck.
This means you could also have changed your loop to:
result = []
for a in (pdf):
result.append(a[50:100].sum())
...but that's what list comprehensions are for :)

In
for i,a in enumerate(pdf):
result.append(a[i][50:100].sum())
a is actually pdf[0], pdf[1], etc. So you calculate sums of pdf[0][0], pdf[1][1], etc.
If you want: take the sum of pdf[0][50:100] and repeat the same for pdf[1][50:100] and so on upto pdf[300][50:100]
you can do
result = [a[50:100].sum() for a in pdf]

Related

How to sum specific elements in an array

I want to sum elements in an array. For example I have an array
[183948, 218520, 243141, 224539, 205322, 203855, 233281, 244830, 281245,
280579, 235384, 183596, 106072, 88773, 63297, 38769, 28343]
I want to sum it in three different parts which are the first three elements, the next 10 elements and the rest.
My only idea is to separate the array and use sum method. Is there better way to do it?
Thanks in advance!
try this:
arr=[183948, 218520, 243141, 224539, 205322, 203855, 233281, 244830, 281245,
280579, 235384, 183596, 106072, 88773, 63297, 38769, 28343]
first=arr[0:3]
second=arr[3:13]
last=arr[13:]
print(sum(first))
print(sum(second))
print(sum(last))
the alternative more extensible version is as follows
arr=[183948, 218520, 243141, 224539, 205322, 203855, 233281, 244830, 281245,
280579, 235384, 183596, 106072, 88773, 63297, 38769, 28343]
indices=[3,13]
results=[]
prev=0
for i in indices:
results.append(sum(arr[prev:i]))
prev=i
results.append(sum(arr[prev:]))
for res in results:
print(res)
note: set prev = to the index you want to start from, in this case 0
You can use the reduceat method of np.add:
data = [183948, 218520, 243141, 224539, 205322, 203855, 233281, 244830, 281245,
280579, 235384, 183596, 106072, 88773, 63297, 38769, 28343]
sizes = 3, 10
np.add.reduceat(data, np.cumsum([0, *sizes]))
# array([ 645609, 2198703, 219182])

Group By Lists python

tests= ['test-2017-09-19-12-06',
'test-2017-09-19-12-05',
'test-2017-09-12-12-06',
'test-2017-09-12-12-05',
'test-2017-09-07-12-05',
'test-2017-09-06-12-07']
So I have the above list, how could I group by the list such that I can get a list which looks like the one below:
[['test-2017-09-19-12-06','test-2017-09-19-12-05'],
['test-2017-09-12-12-06','test-2017-09-12-12-05'],
['test-2017-09-07-12-05'],
['test-2017-09-06-12-07']]
I did try the following code but I get different results, where each string value becomes its own list rather than group by.
from itertools import groupby
print([list(j) for i, j in groupby(tests)])
See that range 0:15, you can use that to determine which segment is used for the grouping.
tests= ['test-2017-09-19-12-06',
'test-2017-09-19-12-05',
'test-2017-09-12-12-06',
'test-2017-09-12-12-05',
'test-2017-09-07-12-05',
'test-2017-09-06-12-07']
pprint.pprint([list(j[1]) for j in groupby(tests,lambda i:i[0:15])])
[['test-2017-09-19-12-06', 'test-2017-09-19-12-05'],
['test-2017-09-12-12-05', 'test-2017-09-12-12-05'],
['test-2017-09-07-12-05'],
['test-2017-09-06-12-07']]
You can split it with by size
tests = ['test-2017-09-19-12-06',
'test-2017-09-19-12-05',
'test-2017-09-12-12-05',
'test-2017-09-12-12-05',
'test-2017-09-07-12-05',
'test-2017-09-06-12-07']
size = 2
[tests[i:i+size] for i in range(0, len(tests), size)]

list index out of bounds for not the obvious reason numpy

I'm not sure why but I keep getting this error, even though the list index does not exceed the number of indexes. The code getting this error is below:
normalisedFaces = np.array([])
for f in range(len(vertextNormalIndices)):
nF1 = vecNormals[vertextNormalIndices[f][0][0]]
nF2 = vecNormals[vertextNormalIndices[f][1][0]]
nF3 = vecNormals[vertextNormalIndices[f][2][0]]
normalisedFaces = np.hstack((normalisedFaces,(np.add(nF1,np.add(nF2,nF3))/ 3)))
print(f)
time.sleep(3)
print(normalisedFaces[f])
My only guess is that I'm reaching the end of the max size of an array(?) For this example, the loop has the range of 529 , but the error comes up when I reach 519. If I change the loop to something like:
for f in range(len(vertextNormalIndices)-200):
Then it reaches the end of the range (so, in this case: 329).
How would one go about fixing this? If possible, I'd prefer not to have to nest this loop and have to split-up the size of each array to e.g. %max==300
Any guidance would be greatly appreciated
I've attached a screenshot of the error here:
The last 8 indexes of vertexNormalIndices: (So, gets the first number of each row e.g. 278, 195, 281)
Per your comments, and looking at your traceback, the error is in this line:
nF1 = vecNormals[vertextNormalIndices[f][0][0]]
So, the error must be that either vertextNormalIndices[519] or vertextNormalIndices[519][0] is an empty list - try printing them out in the loop.
As an aside:
The 'Pythonic' way to iterate through a list is to do it directly, and if you also need to get the index of each element, you should use enumerate:
normalisedFaces = np.array([])
for f, vertexNormalIndex in enumerate(vertextNormalIndices):
nF1 = vecNormals[vertextNormalIndex[0][0]]
nF2 = vecNormals[vertextNormalIndex[1][0]]
nF3 = vecNormals[vertextNormalIndex[2][0]]
normalisedFaces = np.hstack((normalisedFaces,(np.add(nF1,np.add(nF2,nF3))/ 3)))
print(f)
time.sleep(3)
print(normalisedFaces[f])

Confused by output from simple Python loop

I have a list of items and want to remove all items containing the number 16 (here a string, ind='16'). The list has six items with '16' in and yet my loop consistently only removes five of them. Puzzled (I even ran it on two separate machines)!
lines=['18\t4', '8\t5', '16\t5', '19\t6', '15\t7', '5\t8', '16\t8', '21\t8', '20\t12', '22\t13', '7\t15', '5\t16', '8\t16', '21\t16', '4\t18', '6\t19', '12\t20', '8\t21', '16\t21', '13\t22']
ind='16'
for query in lines:
if ind in query:
lines.remove(query)
Subsequently, typing 'lines' gives me: ['18\t4', '8\t5', '19\t6', '15\t7', '5\t8', '21\t8', '20\t12', '22\t13', '7\t15', '8\t16', '4\t18', '6\t19', '12\t20', '8\t21', '13\t22']
i.e. the item '8\t16' is still in the list???
Thank you
Clive
It's a bad idea to modify the list you are iterating over, as removing an item can confuse the iterator. Your example can be handled with a simple list comprehension, which just creates a new list to assign to the original name.
lines = [query for query in lines if ind not in query]
Or, use the filter function:
# In Python 2, you can omit the list() wrapper
lines = list(filter(lambda x: ind not in x, lines))
Note: Never modify list while looping
lines=['18\t4', '8\t5', '16\t5', '19\t6', '15\t7', '5\t8', '16\t8', '21\t8', '20\t12', '22\t13', '7\t15', '5\t16', '8\t16', '21\t16', '4\t18', '6\t19', '12\t20', '8\t21', '16\t21', '13\t22']
ind = '16'
new_lines = [ x for x in lines if ind not in x ]

Python list insert function and datatype issue

I am having an issue and I believe the cause is due to the nature of the insert function.
The documentation says that insert works like so:
list.insert(index, object)
The key point here is "object". In order to conduct an if statement that works on values, I converted my original list into an array. The data-type of this array was automatically calculated by python to be the following:
In [25]: MinorTrendTypeArr.dtype
Out[25]: dtype('int64')
However after inserting the required items in the list
MinorTrendType
The new array,
MinorTrendTypeArr2
As previously mentioned this must be because of the insert function's method of adding object items to the list.
has data-type
In [25]: MinorTrendTypeArr2.dtype
Out[25]: dtype('object')
This is further evidenced by receiving the following error when trying to convert the the
MinorTrendType
variable into the new array.
In [27]: run triptrade.py
This is the length of MinorTrendType the first time = 12356
This is the length of MinorTrendType after adding plustwos elements = 13179
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
/usr/lib/python2.7/dist-packages/IPython/utils/py3compat.pyc in execfile(fname, *where)
173 else:
174 filename = fname
--> 175 __builtin__.execfile(filename, *where)
/home/kane/tripkane_python/triptrade.py in <module>()
579
580 MinorTrendArr2 = np.array(MinorTrend, dtype = np.int64)
--> 581 MinorTrendTypeArr2 = np.array(MinorTrendType, dtype = np.int64)
582
583
ValueError: setting an array element with a sequence.
But the same problem does not arise in variable that did not have external values entered into it. I assume there is probably a way better way of doing things but am using my very limited knowledge at the moment to progress. Any help, suggestions of alternatives would be most welcome. Note: I can not enter all required values in the one loop as entering items changes the length of the list, unless as mentioned there is an easier work around.
Thanks in advance,
Kane
for n in range(0, len(MinorTrendType)):
if MinorTrendTypeArr[n] == 2:
plustwos.append(n)
pl = []
mi = []
PS1 = len(MinorTrendType)
print "This is the length of MinorTrendType the first time = %d" %PS1
for n in range(0, len(plustwos)):
bbgun = plustwos[n] + len(plustwos[0:n])
pl.append(bbgun)
MinorTrendType.insert(pl[n], 22)
MinorTrend.insert(pl[n], MinorTrend[pl[n]])
PS2 = len(MinorTrendType)
print "This is the length of MinorTrendType after adding plustwos elements = %d" %PS2
MinorTrendArr2 = np.array(MinorTrend, dtype = np.int64)
MinorTrendTypeArr2 = np.array(MinorTrendType, dtype = np.int64)
UPDATE/EDIT:
MinorTrendType
is a list of integers like so:
MinorTrendType = [1,0,-1,1,0,-1,2,-1,1,-1,0,0,0,2,1,0,0,-1,2,1,0,-2............]
MinorTrend
is a list of indices where
MinorTrendType
values exist (these simply satisfy certain conditions). All I want to achieve is to insert markers at each occurence of 2 and -2 values within
MinorTrendType
and duplicate index values at the correpsonding sites within
MinorTrend
I have tried using
map(i, x)
int(MinorTrendType[n])
within a loop and list and list comprehensions without success.I hope this makes things clearer. I don't care how it is done, just want to achieve it :)
Hallelujah! The solution as lies in the fact that
MinorTrendArr2.dtype = 'object'
rather than
'int64'
as I suspected. The solution lies in the following loop:
for n in range(0, len(plustwos)):
bbgun = plustwos[n] + len(plustwos[0:n])
pl.append(bbgun)
MinorTrendType.insert(pl[n], 22)
MinorTrend.insert(pl[n], MinorTrend[pl[n]])
This should read:
for n in range(0, len(plustwos)):
bbgun = plustwos[n] + len(plustwos[0:n])
pl.append(bbgun)
MinorTrendType.insert(pl[n], [22])
MinorTrend.insert(pl[n], MinorTrend[pl[n]])
The only difference being that the object being inserted into the list has [ ] around it. Then python assumes the array
MinorTrendArr2
to be
'int64'
instead of object and allows for correct computation of the next if statement :)
Cheers

Categories