Is it possible to format a complex number in such a way that the real part is not displayed if it is zero?
I am currently using '{:.3g}'.format(x) which does a great job of suppressing unnecessary zeros, but I still get numbers of the form 0+0.5j, which should be cast into 0.5j.
Thanks!
str and repr seem to work:
>>> str(0.5j)
'0.5j'
>>> repr(0.5j)
'0.5j'
Related
Consider this:
"{:.14f}".format(0.123)
This will produce the following output:
'0.12300000000000'
But what I would like to have is this:
'0.123'
Is there a standard way to format such a float in a way where trailing zeros are removed automatically? (I'd like to avoid post processing the string as this would be much more expensive than having some formatter do this directly during formatting.)
Sorry, what I've forgot to add to this question a little bit of additional information.
The reason why I need dynamic precision is that I want to avoid the typical exponential notation of floating point numbers. That is the reason why I use something like .14f here: It forces output to not use any e-notation. But unfortunately this adds completely unnecessary tailing zeros. Normally this would not be unnecessary as this output would provide information about the precision, but in this specific case the text output generated shall be parsed again later: It is used for generating SVG graphics. In order to make numbers more human readable I'd like to output them without trailing zeros.
I guess you can just do this to remove the trailing zeroes:
'{0:.14g}'.format(0.123)
Other examples:
>>> '{0:.14g}'.format(0.1230000)
'0.123'
>>> '{0:.14g}'.format(0.12300000000001)
'0.12300000000001'
>>> '{0:.14g}'.format(0.123456789123459)
'0.12345678912346'
To handle scientific representations, you add another processing for it:
'{:.14g}'.format(float('{0:.14f}'.format(0.123)))
i want adding and subtracting this type of data: $12,587.30.which returns answer in same format.how can do this ?
Here is my code example:
print(int(col_ammount2.lstrip('$'))-int(col_ammount.lstrip('$')))
I removed $ sign and convert it to int but it gives me base 10 error.
You mentioned you want to do arithmetic operations to the numbers (addition/subtraction) so you probably want them in float instead. The difference between an integer (int) and float is that integers do not carry decimal points.
Additionally, as #officialaimm mentioned you need to remove the commas too, for example
float('$3,333.33'.replace('$', '').replace(',', ''))
will give you
3333.33
So putting it into your code
print(float(col_ammount2.lstrip('$').replace(',', ''))
- float(col_ammount.lstrip('$').replace(',', '')))
An additional note for when you parse a floating point number (same applies to integers too), you may want to watch out for empty values, i.e.
float('')
is bad. One of the things u can do in case col_amount and col_amount2 may be empty at some point is default them to 0 if that happens
float(col_amount.lstrip(...).replace(...) or 0)
You also want to read this to know about workaround to problems you may face with floating point arithmetic https://docs.python.org/3/tutorial/floatingpoint.html
There are two things you are missing here. Firstly python int(...) cannot parse numbers with commas so you will need to remove commas as well by using .replace(',',''). Secondly int() cannot parse floating point values you will have to use float(...) first and after that maybe typecast it to int using int or math.ceil, math.floor appropriately as per your choice and needs.
Maybe something like this will solve your problem:
col_ammount2='$1,587.30'
col_ammount = '$2,567.67'
print(int(float(col_ammount2.lstrip('$').replace(',','')))-int(float(col_ammount.lstrip('$').replace(',',''))))
If you are doing these sorts of things quite often in your code, making a function as such might be handy:
integerify_currency = lambda x:int(float(x.lstrip('$').replace(',','')))
I tried to compute math.exp(9500) but encountered an OverflowError: math range error (it's roughly 6.3e4125). From this question it seems like it's due to a too large float, the accepted answer says "(...) is slightly outside of the range of a double, so it causes an overflow".
I know that Python can deal with arbitrarily large integers (long type), is there a way to deal with arbitrarily large floats in the same manner ?
Edit : my original question was about using integers for calculating exp(n) but as Eric Duminil said, the simplest way to do that would be 3**n which doesn't provide any useful result. I know realize this question might be similar to this one.
I don't think it's possible to approximate exp() with integers. If you use 3**n instead of 2.71828182845905**n, your calculations will be completely useless.
One possible solution would be to use Sympy. According to the documentation:
There is essentially no upper precision limit
>>> from sympy import *
>>> exp(9500)
exp(9500)
>>> exp(9500).evalf()
6.27448493490172e+4125
You can also specify the desired precision:
>>> exp(9500).evalf(1000)
6.274484934901720177929867046175406311474380389941415760684209191232450360090766458256588885184199320756050569665785657269735313171886975309933254563488343491718198237894473901620914303565550450204805537225888529509352754121292701357622411614860860409639719786022989336837263283678476008817556351031696366815467221836948040042378034720460820127399855873232167818091083005170669482845098735176209372328114732133251096196535355946589133977397512846130629857604295369747597459602137604440011394793443041829253598478244189078131130488653468669559814695095974271938947640276013215753183113041899037415404445478806695965167014404297848725756879184380559837391976534521522360723388582608454995349380217499779247330557664230806254642768796486899322646423713763772064068933790640394967085887914192401473425799354391464743910233873602389444180426155866237536459654917521713769608318128404177877383203786348495822099924812081683286880293701785567962687838594752986160305764297117036426951203418854463404773701882e+4125
With exp(9500).evalf(5000), you even get the integer closest to exp(9500).
Here's another way to calculate the result with Python:
exp(9500)
is too big.
But log10(exp(9500)) isn't. You cannot calculate it this way in Python, but log10(exp(9500)) is log(exp(9500))/ln(10), which is 9500/ln(10):
>>> from math import log
>>> 9500/log(10)
4125.797578080892
>>> int(9500/log(10))
4125
>>> 10**(9500/log(10) % 1)
6.274484934896202
This way, you can calculate that exp(9500) is 6.27448493 * 10**4125 in plain Python, without any library!
try long type.
int type has been remove from python since 3.0 version.
This question is very similar to this post - but not exactly
I have some data in a .csv file. The data has precision to the 4th digit (#.####).
Calculating the mean in Excel or SAS gives a result with precision to 5th digit (#.#####) but using numpy gives:
import numpy as np
data = np.recfromcsv(path2file, delimiter=';', names=['measurements'], dtype=np.float64)
rawD = data['measurements']
print np.average(rawD)
gives a number like this
#.#####999999999994
Clearly something is wrong..
using
from math import fsum
print fsum(rawD.ravel())/rawD.size
gives
#.#####
Is there anything in the np.average that I set wrong _______?
BONUS info:
I'm only working with 200 data points in the array
UPDATE
I thought I should make my case more clear.
I have numbers like 4.2730 in my csv (giving a 4 decimal precision - even though the 4th always is zero [not part of the subject so don't mind that])
Calculating an average/mean by numpy gives me this
4.2516499999999994
Which gives a print by
>>>print "%.4f" % np.average(rawD)
4.2516
During the same thing in Excel or SAS gives me this:
4.2517
Which I actually believe as being the true average value because it finds it to be 4.25165.
This code also illustrate it:
answer = 0
for number in rawD:
answer += int(number*1000)
print answer/2
425165
So how do I tell np.average() to calculate this value ___?
I'm a bit surprised that numpy did this to me... I thought that I only needed to worry if I was dealing with 16 digits numbers. Didn't expect a round off on the 4 decimal place would be influenced by this..
I know I could use
fsum(rawD.ravel())/rawD.size
But I also have other things (like std) I want to calculate with the same precision
UPDATE 2
I thought I could make a temp solution by
>>>print "%.4f" % np.float64("%.5f" % np.mean(rawD))
4.2416
Which did not solve the case. Then I tried
>>>print "%.4f" % float("4.24165")
4.2416
AHA! There is a bug in the formatter: Issue 5118
To be honest I don't care if python stores 4.24165 as 4.241649999... It's still a round off error - NO MATTER WHAT.
If the interpeter can figure out how to display the number
>>>print float("4.24165")
4.24165
Then should the formatter as well and deal with that number when rounding..
It still doesn't change the fact that I have a round off problem (now both with the formatter and numpy)
In case you need some numbers to help me out then I have made this modified .csv file:
Download it from here
(I'm aware that this file does not have the number of digits I explained earlier and that the average gives ..9988 at the end instead of ..9994 - it's modified)
Guess my qeustion boils down to how do I get a string output like the one excel gives me if I use =average()
and have it round off correctly if I choose to show only 4 digits
I know that this might seem strange for some.. But I have my reasons for wanting to reproduce the behavior of Excel.
Any help would be appreciated, thank you.
To get exact decimal numbers, you need to use decimal arithmetic instead of binary. Python provides the decimal module for this.
If you want to continue to use numpy for the calculations and simply round the result, you can still do this with decimal. You do it in two steps, rounding to a large number of digits to eliminate the accumulated error, then rounding to the desired precision. The quantize method is used for rounding.
from decimal import Decimal,ROUND_HALF_UP
ten_places = Decimal('0.0000000001')
four_places = Decimal('0.0001')
mean = 4.2516499999999994
print Decimal(mean).quantize(ten_places).quantize(four_places, rounding=ROUND_HALF_UP)
4.2517
The result value of average is a double. When you print out a double, by default all digits are printed. What you see here is the result of limited digital precision, which is not a problem of numpy, but a general computing problem. When you care of the presentation of your float value, use "%.4f" % avg_val. There is also a package for rational numbers, to avoid representing fractions as real numbers, but I guess that's not what you're looking for.
For your second statement, summarizing all the values by hand and then dividing it, I suppose you're using python 2.7 and all your input values are integer. In that way, you would have an integer division, which truncates everything after the dot, resulting in another integer value.
I want to use python to write code for another language which doesn't understand exponentially formatted floats. Is there an easy way to get python to, when converting floats to strings, use long-form notation (I.E. 0.000000009 instead of 9e-9)? I tried '%(foo)f', but it cuts the decimal short (0.00000).
Try something like
"%.16f" % f
This will still use exponential format if the number is too small, so you have to treat this case separately, for example
"%.16f" % f if f >= 1e-16 else "0.0"
Use a specific format specifier, e.g.:
>>> f=9*(10**-9)
>>> str(f)
'9e-09'
>>> "%.23f" % f
'0.00000000900000000000000'
UPDATE (thanks to #Sven): The amount of digits you want to use depends on the magnitude of the number. if you have large numbers (like several trillions) you won't need any decimals, obviously. for tiny numbers you need more. 'tis an ugly representation indeed.