Just a small and probably very simple question. Someone gave me the following line of code:
im = axs[0,i].pcolormesh(imgX[o:,:], imgY[o:,:], img.mean(-1)[o:,:], cmap='Greys')
I know ":" means everything in that column or row (or array depth, depending on how you look at it). But what does "o:" mean?
The following is not related to the usage, but shows how the operation "is parsed".
class X:
def __getitem__(self, index):
return index
X()[:,:]
>> (slice(None,None,None), slice(None,None,None))
And with different values for clarity:
X()[0, 1:, 3:4, 5:6:7]
>> (0, slice(1,None,None), slice(3,4,None), slice(5,6,7))
So, with that in mind img[o:,:] is like img[o:, :] is like
img.__getitem__( (slice(o,None,None), slice(None,None,None)) )
o is a variable like any other (but with a very bad name, as it can be confused with a zero).
[o:, :] means "all the elements from the first axis starting in the element o, and all in the second axis. In your particular case, the image will show only the rows from o to the bottom.
I want to add that in this case, you are getting a view, i.e., a reference to the original array, so the data is not actually copied.
Related
I'm very new to coding and have searched heavily to try to find an answer to this.
I have a (10,10) array and am trying to add across two specific rows a specific value. I am also trying to do it with a single line of code.
Specifically, I am trying to add across the sixth and 8th row of the array the value present at the specific element of that same array (5,5). My array is defined as 'a'.
I feel like a for loop could work, but the problem is that 1) this is two lines of code, and 2, it produces something close but is adding that element to those two rows, twice instead of once.
for x in a[(5,7),:]:
a[(5,7),:] = (x + (a[5,5])):
You've probably over-complicated this a bit. If I understand correctly, you should do something like this:
a[(5, 7), :] += a[5, 5]
The += operator is an "in-place" addition. This is the same as doing this:
a[(5, 7), :] = a[(5, 7), :] + a[5, 5]
I'm quite new to programming (in Python) and so I don't understand what is going on here. I have an image (35x64) as a 3D-array and with np.mean(), I attempted to extract the mean of one color channel of one row:
print(np.mean(img[30][:][0]))
For comparison, I also wrote a for-loop to append the exact same values in a list and calculating the mean with that:
for i in range(64):
img_list.append(img[30][i][0])
print(np.mean(img_list))
Now, for a strange reason, it gives different values:
First output: 117.1
Second output: 65.7
By looking at the list, I discovered that the second one is correct. Can somebody with more experience explain to me why this is exactly happening and how to fix that? I don't want to use the second, longer code chunk in my programs but am searching for a 1-line solution that gives a correct value.
There's a subtle difference between img[30][:][0] and img[30,:,0] (the one you were expecting).
Let's see with an example:
img = np.arange(35*64*3).reshape(35,64,3)
img[30][:][0]
# array([5760, 5761, 5762])
img[30,:,0]
# array([5760, 5763, ... 5946, 5949])
So you simply need to:
print(np.mean(img[30,:,0]))
(which is more efficient anyways).
Some details: in your original syntax, the [:] is actually just triggering a copy of the array:
xx = img[30]
yy = img[30][:]
print (xx is yy, xx.shape, yy.shape, np.all(xx==yy))
# False (64, 3) (64, 3) True # i.e. both array are equal
So when you take img[30][:][0], you're actually getting the 3 colors of the first pixel of row 30.
I'm fairly new to python and I'm working on a bit of a complicated (but fun!) project. I won't go into too many details, but I've noticed that previous questions similar to this tend to be for very specific situations, which makes them more difficult for me to get anything out of, but surely easier for people to try to answer.
I'm essentially working with a 36x36 matrix (simply called "array" in my code), where the bottom-left corner is entry 0, the entry above that is 1, and so on until we reach the 36th entry at the top-left corner and come back down to the 37th entry being to the right of entry 0, etc. For a given entry, I want to know the values of the entries to the right, left, up, and down of the argument. Of course, there are several edge cases that won't have 4 neighbors, so I've made an effort to take those into account, but I am getting seemingly inconsistent errors.
Here's the latest thing I've tried:
def neighbors(i):
neighbors_array = []
if array[i+1] in array:
neighbors_array.append(array[i+1])
if array[i-1] in array:
neighbors_array.append(array[i-1])
if array[i+36] in array:
neighbors_array.append(array[i+36])
if array[i-36] not in array:
neighbors_array.append(array[i-36])
return neighbors_array
For an argument in the middle of the array, say 800, I get 4 values that perfectly match what I would get if i individually printed array[i+1], array[i-1], etc. But for an argument I know is in the leftmost column of the matrix I get an output array with 4 entries even though I'm only expecting 3 since the argument doesn't have an [i-36] element associated to it. For an argument I know is in the rightmost column, I get IndexError: list index out of range
I'm confused as to why both edge cases don't have the same problem, and I want to fix both issues. As for entries in the top and bottom rows, I also get an unexpected 4-entry output, with the exceptions of the top-right and bottom-right corners, for which I get the index error.
I've tried converting the array to an actual matrix, but the neighbors function output is more complicated and I get similar problems anyways, so I think I'd rather stick with the array.
This doesn't work as a bounds check:
if array[i-1] not in array:
pass
because as soon as you say array[i-1] you're going to raise an exception, before your if predicate is even done evaluating. You need to check that i is a valid index before you use it as an array index.
This would be the idiomatic way of doing this type of bounds check:
if i not in range(len(array)):
For your specific use case where you want to "wrap" values that are out of bounds, I'd suggest using the modulo (%) operator rather than using bounds checks to individually wrap in one direction or another. Just let math do the work for you. :)
for neighbor in [i-1, i+1]:
neighbors_array.append(array[neighbor % len(array)])
since 36 % 36 == 0, -1 % 36 == 35, etc.
The actual problem you see is in the code array[something] in array (originally array[i+36] not in array and so on).
If we try to evaluate this step by step we get the following:
first array[something] is evaluated. That might lead to an IndexError. If it succeeds we have some value
now value in array is evaluated which in our case will be always True as we did previously get the value from the array itself.
Solution:
For lists you should check the length of the list to prevent IndexError:
if len(array) > i+36:
do_whatever_with(array[i+36])
Pythonic aproach:
In python it is considered good style to "ask for forgiveness instead of permission", so instead of the if-in-range-do pattern you could use a try-access-except-cleanup pattern:
try:
do_whatever_with(array[i+36])
except IndexError:
pass # because you just skipped the case in your original code as well
Good evening, StackOverflow.
Lately, I've been wrestling with a Python program which I'll try to outline as briefly as possible.
In essence, my program plots (and then fits a function to) graphs. Consider this graph.
The graph plots just fine, but I'd like it to do a little more than that: since the data is periodic over an interval OrbitalPeriod (1.76358757), I'd like it to start with our first x value and then iteratively plot all of the points OrbitalPeriod away from it, and then do the same exact thing over the next region of length OrbitalPeriod.
I know that there is a way to slice lists in Python of the form
croppedList = List[a:b]
where a and b are the indices of the first and last elements you'd like to include in the new list, respectively. However, I have no idea what the indices are going to be for each of the values, or how many values fall between each OrbitalPeriod-sized interval.
What I want to do in pseudo-code looks something like this.
croppedList = fullList on the domain [a + (N * OrbitalPeriod), a + (N+1 * OrbitalPeriod)]
where a is the x-value of the first meaningful data point.
If you have a workaround for this or a cropping method that would accept values instead of indices as arguments, please let me know. Thanks!
If you are working with numpy, you can use it inside the brackets
m = x
M = x + OrbitalPeriod
croppedList = List[m <= List]
croppedList = croppedList[croppedList < M]
I have a 40 - dimension numpy vector with values like -0.399917 ,0.441786 ...
The data type of the vector by default is |S8 (String)
When I try to change the dtype using the astype method, I get the following error --
ValueError: could not convert string to float:
My partial ode
value=np.array(value)
value.astype(float)
I don't have your exact dataset, but the following code worked for me:
a = np.array(['-0.399917', '0.441786']) # (Line 1)
dim = (2, 2, 2, 2)
a = np.tile(a, dim)
b = a.astype(float)
I know the dimensions aren't the same as you have, but that shouldn't make a difference. What is likely happening is that some of the values in your vector are not of the form you specified. For example, the following both raise your ValueError when they are used in (Line 1):
a = np.array(['-0.399917', '0.441786', ''])
a = np.array(['-0.399917', '0.441786', 'spam'])
It is likely that you have either empty values, string values, or something similar in your array somewhere.
If the values are empty, you can do something like was suggested here:
a[a==''] = '0'
or whatever value you want it to be. You can do a similar thing with other string values as long as they have a pattern. If they don't have a pattern, you can still do this, but it may not be feasible to go through looking for all the possibilities.
EDIT: If you don't care what the strings are, you just want them turned into nan, you can use np.genfromtxt as explained here. That might or might not be dangerous, depending on your application. Often, codes are given to indicate something about the array element and you might not want to treat them all the same.