Printing numpy.float64 with full precision - python

What is the proper/accepted way to print and convert a numpy.float64 to a string? I've noticed just using print or str() will lose some precision. However, repr maintains the full precision. For example:
>>> import numpy
>>> print numpy.float64('6374.345407799015')
6374.3454078
>>> print repr(numpy.float64('6374.345407799015'))
6374.3454077990154
I assume that just calling print turns into calling str() on the float64 object. So is __str__() for numpy.float64 implemented with something like '%s' % (float(self)) or somehow casts the float64 with Python's built-in float()? I tried to quickly look around the numpy source for this but wasn't immediately obvious what was happening.
I've always thought repr() should return valid Python code that could be used by eval() to re-create the object. Is this an accepted convention? Luckily in this case numpy does not follow this convention because repr() returns just the raw number as a string instead of something like "numpy.float64('6374.345407799015')".
So, all of this confuses me. What is the correct way to convert a numpy.float64 to a string and/or print it while guaranteeing you always have the same, full precision?

The astype method works well:
>>> numpy.float64('6374.345407799015').astype(str)
'6374.345407799015'

Look into numpy.set_printoptions. Specifically,
numpy.set_printoptions(precision=15)

Related

How to convert mathematical numbers into floats

In python, is there a way or even build in Function to convert a string into a float? Specifically:+1.488763E+01 into 14.88763 ?
What you have is a valid float literal. Convert it to a float, then convert the result back to a str
>>> '{:f}'.format(float('+1.488763E+01'))
'14.887630'
The format method is used to force the value to be represented as a fixed-point value, rather than in exponential notation. For example,
>>> str(float('1e20'))
'1e+20'
>>> '{:f}'.format(float('1e20'))
'100000000000000000000.000000'
Python does this conversion automatically. Just try it.
a = +1.488763E+01
print(a)
14.88763
It’s a decimal, it already is a float. Though if you print it, python will automatically put it in the format you want.
As long as you don’t have it as a string, it’ll be in the format you want it.
a = +1.488763E+01
print(a)
14.88763
You can use float() function
float(a)

Longdouble(1e3000) becomes inf: What can I do?

(Most other related questions in the web concern conversion between C's longdouble and python's. This question is different.)
I do not see why I cannot correctly get a longdouble in python like this:
In [72]: import numpy as np
In [73]: np.longdouble(1e3000)
Out[73]: inf
It seems that I need to let my python console know 1e3000 is a longdouble instead of double. How can I do that
The problem is that by using an expression like ...(1e3000), the Python parser has to calculate what is inside the parentheses first, and pass the result to the function call. Long double is not a native type, therefore, the value inside the parentheses is inf - which is passed to the longdouble constructor. The fact the string version fails could maybe be considered a bug in NumPy - it indicates the string is converted to a Python float (which is a "float64" or "double" in C) internally, possibly using the normal Python float constructor.
The workaround is to build the long double object first, with a value that is compatble with a Python float, and them multiply it to get to the desired value. If you need to do that with several values, use a NumPy array instead of a single value:
>>> x = np.longdouble(10)
>>> x
10.0
>>> x **= 3000
>>> x
9.9999999999999999999e+2999
Python doesn't have "long doubles". By using scientific notation, you are making a float literal. Those cannot represent 1e3000, so you get inf. If you use integers, you might be able to do what you need: 10**3000.

Python precision of float is lost while converting to string

I am using Scapy's sniff function for reading packets from a pcap file.
pkt=sniff(offline="a.pcap",count=1)[0]
In IDLE with pkt.time, I am able to get the time-stamp of the packet i.e. 1431063004.998014. But when I tried to convert the time-stamp to a string with str(pkt.time) or instead of pkt.time I give print pkt.time, I get only 1431063005.0.
Is it possible to get the exact time-stamp value as a string??
Note:
I looked in to decimal module. But that requires the precision number. That won't help without knowing the number of digits, I guess.
repr is another method like str which converts the whole float with precision. No need to import decimal or anything. Use it just like you use str and it returns a str object only.
>>> x = repr(pkt.time)
>>> type(x)
>>> <type 'str'>
Try this one:
"{:.6f}".format(pkt.time)
try this:
"{:.6f}".format(pkt.time)

python string formatting {:d} vs %d on floating point number

I realise that this question could be construed as similar to others, so before I start, here is a list of some possible "duplicates" before everyone starts pointing them out. None of these seem to really answer my question properly.
Python string formatting: % vs. .format
"%s" % format vs "{0}".format() vs "?" format
My question specifically pertains to the use of the string.format() method for displaying integer numbers.
Running the following code using % string formatting in the interpreter running python 2.7
>>> print "%d" %(1.2345)
1
Whereas using the string.format() method results in the following
>>> print "{:d}".format(1.2345)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Unknown format code 'd' for object type 'float'
I was expecting the same behavior in both; for the interpreter to actually convert my floating point number to an integer prior to displaying. I realise that I could just use the int function to convert the floating point number to integer format, but I was looking for the same functionality you get with the %d formatting method. Is there any string.format() method that would do this for me?
The two implementations are quite separate, and some warts in the % implementation were ironed out. Using %d for floats may mask problems in your code, where you thought you had integers but got floating point values instead. Imagine a value of 1.999999 and only seeing 1 instead of 2 as %d truncates the value.
As such, the float.__format__() hook method called by str.format() to do the actual conversion work does not support the d format and throws an exception instead.
You can use the {:.0f} format to explicitly display (rounded) floating point values with no decimal numbers:
>>> '{:.0f}'.format(1.234)
'1'
>>> '{:.0f}'.format(1.534)
'2'
or use int() before formatting to explicitly truncate your floating point number.
As a side note, if all you are doing is formatting a number as a string (and not interpolating into a larger string), use the format() function:
>>> format(1.234, '.0f')
'1'
This communicates your intent better and is a little faster to boot.
There is an important change between 2.7 and 3.0 regarding "automatic type conversion" (coercion). While 2.7 was somehow relatively "relax" regarding this, 3.0 forces you to be more disciplined.
Automatic conversion may be dangerous, as it may silently truncate/reduce some data ! Besides, this behavior is inconsistent and you never know what to expect; until you're faced with he problem. Python 3.0 requires that you specify what you want to, precisely, do !
However, the new string.format() adds some very powerful and useful formatting techniques. It's even very clear with the "free" format '{}'. Like this :
'{}'.format(234)
'{:10}.format(234)
'{:<10}'.format(234)
See ? I didn't need to specify 'integer', 'float' or anything else. This will work for any type of values.
for v in (234, 1.234, 'toto'):
for fmt in ('[{}]', '[{:10}]', '[{:<10d}]', '[{:>10d}]'):
print(fmt.format(v))
Besides, the % value is obsolete and should not be used any more. The new string.format() is easier to use and has more features than the old formatting techniques. Which, IMHO, renders the old technique less attractive.

Converting a string-like object into a string in python

I am using python and XMLBuilder, a module I downloaded off the internet (pypi). It returns an object, that works like a string (I can do print(x)) but when I use file.write(x) it crashes and throws an error in the XMLBuilder module.
I am just wondering how I can convert the object it returns into a string?
I have confirmed that I am writing to the file correctly.
I have already tried for example x = y although, as I thought, it just creates a pointer, and also x=x+" " put I still get an error. It also returns an string like object with "\n".
Any help on the matter would be greatly appreciated.
file.write(str(x))
will likely work for you.
Background information: Most types have a function __str__ or __repr__ (or both) defined. If you pass an object of such a type to print, it'll recognize that you did not pass a str and try to call one of these functions in order to convert the object to a string.
However, not all functions are as smart as print and will fail if you pass them something that is not a string. Also string concatenation does not work with mixed types. To work with these functions you'll have to convert the non-string-type objects manually, by wrapping them with str(). So for example:
x = str(x)+" "
This will create a new string and assign it to the variable x, which held the object before (you lose that object now!).
The Library has __str__ defined:
def __str__(self):
return tostring(~self, self.__document()['encoding'])
So you just need to use str(x):
file.write(str(x))
I'm not quite sure what your question is, but print automatically calls str on all of it's arguments ... So if you want the same output as print to be put into your file, then myfile.write(str(whatever)) will put the same text in myfile that print (x) would have put into the file (minus a trailing newline that print puts in there).
When you write:
print myObject
The __repr__ method is actually called.
So for example you could do: x += myXMLObject.__repr__() if you want to append the string representation of that object to your x variable.

Categories