Max value of array won't save ASCII text to file - python

I am reading points from a frequency spectrum graph into an array like this:
self.iq_fft = self.dofft(self.iq)#Gets values of all data point in block (in dB)
x = self.iq_fft #puts values into x for simplicity
maxi = max(x)
print maxi #This part works fine
def dofft(self, iq):
N = len(iq)
iq_fft = scipy.fftpack.fftshift(scipy.fft(iq))
Everything works great and it prints out the maximum value of the array to the screen perfect, however, when I try to save the max value to a file, like this:
savetxt('myfilelocation', maxi, fmt='%1.4f')#saves max(x) in binary format
It ends up saving the binary value to the text file and not the nice pretty ASCII one that printed to the screen. Funny thing is, when I just dump the whole array to a file it looks fine. Any ideas on how to fix this?

numpy.savetxt saves an array to a file, and it looks like maxi is a python Float. It's sort of unusual to use savetxt to save a scalar (why not just use Python's built-in file i/o functions?), but if you must, this might work:
savetxt('myfilelocation', [maxi], fmt='%1.4f')
Notice that I've put maxi in a list. Also, make sure that myfilelocation doesn't end with a .gz. If it does, numpy will compress it. When it doubt, just use .txt, or no extension at all.

Related

(Python3.x)Splitting arrays and saving them into new arrays

I'm writing a Python script intended to split a big array of numbers into equal sub-arrays. For that purpose, I use Numpy's split method as follows:
test=numpy.array_split(raw,nslices)
where raw is the complete array containing all the values, which are float64-type by the way.
nslices is the number of sub-arrays I want to create from the raw array.
In the script, nslices may vary depending of the size of the raw array, so I would like to "automatically" save each created sub-arrays in a particular array as : resultsarray(i)in a similar way that it can be made in MATLAB/Octave.
I tried to use afor in range loop in Python but I am only able to save the last sub-array in a variable.
What is the correct way to save the sub-array for each each incrementation from 1 to nslices?
Here, the complete code as is it now (I am a Python beginner, please bother the low-level of the script).
import numpy as np
file = open("results.txt", "r")
raw = np.loadtxt(fname=file, delimiter="/n", dtype='float64')
nslices = 3
rawslice = np.array_split(raw,nslices)
for i in range(0,len(rawslice)):
resultsarray=(rawslice[i])
print(rawslice[i])
Thank you very much for your help solving this problem!
First - you screwed up delimiter :)
It should be backslash+n \n instead of /n.
Second - as Serge already mentioned in comment you can just access to split parts by index (resultarray[0] to [2]). But if you really wanted to assign each part to a separate variable you can do this in fommowing way:
result_1_of_3, result_2_of_3, result_3_of_3 = rawslice
print(result_1_of_3, result_2_of_3, result_3_of_3)
But probably it isn't the way you should go.

How to do math operation on imported csv data?

I have read in a csv file ('Air.csv') and have performed some operations to get rid of the header (not important). Then, I used dB_a.append(row[1]) to put this column of the csv data into an array which I could later plot.
This data is dB data, and I want to convert this to power using the simple equation P = 10^(dB/10) for every value. I am new to Python, so I don't quite understand how operations within arrays, lists, etc. works. I think there is something I need to do to iterate over that full data set, which was my attempt at a for loop, but I am still receiving errors. Any suggestions?
Thank you!
frequency_a=[]
dB_a=[]
a = csv.reader(open('Air.csv'))
for row in itertools.islice(a, 18, 219):
frequency_a.append(row[0])
dB_a.append(row[1])
#print(frequency_a)
print(dB_a)
for item in dB_a:
power_a = 10**(dB_a/10)
print(power_a)
In your for loop, item is the iterator, so you need to use that. So instead of:
power_a = 10**(dB_a/10)
use:
power_a = 10**(item/10)
A nicer way to create a new list with that data could be:
power_a = [10**(db/10) for db in dB_a]
EDIT: The other issue as pointed out in the comment, is that the values are strings. The .csv file is essentially a text file, so a collection of string, rather than integers. What you can do is convert them to numeric values using int(db) or float(db), depending whether you have whole or floating point numbers.
EDIT2: As pointed out by #J. Meijers, I was using multiplication instead of exponentiation - this has been fixed in the answer.
To build on the answer #ed Jaras posted.
power_a = [10*(db/10) for db in dB_a]
is not correct, since this divides by 10, and then multiplies by the same.
It should be:
power_a = [10**(db/10) for db in dB_a]
Credits still go to #Ed Jaras though
Note:
If you're wondering what this [something for something in a list] is, it is a list comprehension. They are amazingly elegant constructs that python allows.
What is basically means is [..Add this element to the result.. for ..my element.. in ..a list..].
You can even add conditionals to them if you want.
If you want to read more about them, I suggest checking out:
http://www.secnetix.de/olli/Python/list_comprehensions.hawk
Addition:
#k-schneider: You are probably doing numerical operations (dividing, power, etc. ) on a string, this is because when importing a csv, it is possible for fields to be imported as a string.
To make sure that you are working with integers, you can cast db to a string by doing:
str(db)

Store data based on location in a dataset python

Forgive me if this question is trivial, I am just having some trouble finding a solution online, and I'm a bit new to python. Essentially, I have a dataset which is full of various numbers all of which are arranged in this format:
6.1101,17.592
5.5277,9.1302
8.5186,13.662
I'm trying to write some python to get the number on either side of the comma. I assume it's some type of splitting, but I can't seem to find anything that works for this problem specifically since I want to take the ALL the numbers from the left and store them in a variable, then take ALL the numbers on the right store them in a variable. The goal is to plot the data points, and normally I would modify the data set, but it's a challenge problem so I am trying to figure this out with the data as is.
Here's one way:
with open('mydata.csv') as f:
lines = f.read().splitlines()
left_numbers, right_numbers = [], []
for line in lines:
numbers = line.split(',')
left_num = float(numbers[0])
right_num = float(numbers[1])
left_numbers.append(left_num)
right_numbers.append(right_num)
Edit: added float conversion

Trying to fill an array with data opened from files

the following is code I have written that tries to open individual files, which are long strips of data and read them into an array. Essentially I have files that run over 15 times (24 hours to 360 hours), and each file has an iteration of 50, hence the two loops. I then try to open the files into an array. When I try to print a specific element in the array, I get the error "'file' object has no attribute 'getitem'". Any ideas what the problem is? Thanks.
#!/usr/bin/python
############################################
#
import csv
import sys
import numpy as np
import scipy as sp
#
#############################################
level = input("Enter a level: ");
LEVEL = str(level);
MODEL = raw_input("Enter a model: ");
NX = 360;
NY = 181;
date = 201409060000;
DATE = str(date);
#############################################
FileList = [];
data = [];
for j in range(1,51,1):
J = str(j);
for i in range(24,384,24):
I = str(i);
fileName = '/Users/alexg/ECMWF_DATA/DAT_FILES/'+MODEL+'_'+LEVEL+'_v_'+J+'_FT0'+I+'_'+DATE+'.dat';
FileList.append(fileName);
fo = open(fileName,"rb");
data.append(fo);
fo.close();
print data[1][1];
print FileList;
EDITED TO ADD:
Below, find the CORRECT array that the python script should be producing (sorry it wont let me post this inline yet):
http://i.stack.imgur.com/ItSxd.png
The problem I now run into, is that the first three values in the first row of the output matrix are:
-7.090874
-7.004936
-6.920952
These values are actually the first three values of the 11th row in the array below, which is the how it should look (performed in MATLAB). The next three values the python script outputs (as what it believes to be the second row) are:
-5.255577
-5.159874
-5.064171
These values should be found in the 22nd row. In other words, python is placing the 11th row of values in the first position, the 22nd in the second and so on. I don't have a clue as to why, or where in the code I'm specifying it do this.
You're appending the file objects themselves to data, not their contents:
fo = open(fileName,"rb");
data.append(fo);
So, when you try to print data[1][1], data[1] is a file object (a closed file object, to boot, but it would be just as broken if still open), so data[1][1] tries to treat that file object as if it were a sequence, and file objects aren't sequences.
It's not clear what format your data are in, or how you want to split it up.
If "long strips of data" just means "a bunch of lines", then you probably wanted this:
data.append(list(fo))
A file object is an iterable of lines, it's just not a sequence. You can copy any iterable into a sequence with the list function. So now, data[1][1] will be the second line in the second file.
(The difference between "iterable" and "sequence" probably isn't obvious to a newcomer to Python. The tutorial section on Iterators explains it briefly, the Glossary gives some more information, and the ABCs in the collections module define exactly what you can do with each kind of thing. But briefly: An iterable is anything you can loop over. Some iterables are sequences, like list, which means they're indexable collections that you can access like spam[0]. Others are not, like file, which just reads one line at a time into memory as you loop over it.)
If, on the other hand, you actually imported csv for a reason, you more likely wanted something like this:
reader = csv.reader(fo)
data.append(list(reader))
Now, data[1][1] will be a list of the columns from the second row of the second file.
Or maybe you just wanted to treat it as a sequence of characters:
data.append(fo.read())
Now, data[1][1] will be the second character of the second file.
There are plenty of other things you could just as easily mean, and easy ways to write each one of them… but until you know which one you want, you can't write it.

Manipulating data arrays and adding noise

I just cannot seem to get this right! :-(
I have a code that is supposed to read in a .fits file, add normally distributed noise to it, and then re-save that code. So far, it just does not seem to be working at all. There's a lot of extra code, so I only posted the portion that's relevant. Assume that everything that this slice of code needs to read in exists, because it does. The goal of this code is to take a .fits file and add normally distributed noise to the pixels, then save that file. "poisson" is a previously inputted variable, i.e. a "poisson" value of 1 corresponds to one standard deviation from the mean of zero. Yes, the word "poisson" is a bit of a misnomer, and I should really rehaul my code to amend that.
My first issue is . . . what does im0 = im[0] mean? It doesn't seem like it's the first row of pixels in the .fits file, because when I change the integer in the brackets to anything besides "0", I get an index error. On top of that, the normalNoise = np.random.normal(0,poisson) method is incomplete because I'm missing a third parameter, "size" (tuple of ints) and I have no idea what that means. My images are 130 pixels x 130 pixels, if that means anything.
im = pf.open(name)
im0 = im[0]
normalNoise = np.random.normal(0,poisson)
print im0.data
test = im0.data + normalNoise
print test
im0.data = test
stringee = 'NOISE'
pf.writeto(stringee+str(poisson)+name, data=test, clobber=True, header=im0.header)
print poisson
This should ideally spit out the same image but with added noise, except it doesn't!
I do not know the underlying library, but if pf is a FITS file, im[0] is probably
creating a reference to the primary HDU; if there is only a primary HDU (as for
any simple-minded FITS file with only a single image), any higher index leads to an error.

Categories