Remove decimals from a Float column - python

shocked beyond belief how difficult this is turning out to be. All I can find are suggestions to change the format of the column to 'int' but I need to keep the comma thousand separators and changing the format to int gets rid of them. THEN i can't find anything on how to add comma separators to an int column. any ideas? really is nothing for me to share in addition to above in terms of what i've tried.

Format your floats...in a string format?
my_string = '{:,.0f}'. format(my_number)
E.g.:
x = 1000.00
'{:,.0f}'. format(x)-> 1,000
Which gives you what you want...something you can print with commas. 0f sets to 0 precision. (for how many decimal places)

Related

Pandas: parse .csv string type number with dot as thousand separator to int instead of float

It's a .csv with items and prices. The latter already come rounded (without decimal) but if the price is more than 999, then I have to deal with the thousand separator.
item, price
foo, 12
bar,678
baz, 1.200
`df.dtype` returns:
item object
price float64
If I try to convert to int it truncates the number. So instead of 1.200 (one thousand two hundred) I get 1 (one)
Ps: I winded up deleting the dots with regex, but there has to be a proper way to handle this situation.
As mentioned by #BigBen there's a pd.read_csv parameter called thousands used to indicate the thousand separator. There's also a decimal parameter which may be useful too.

Format str to float and increase from 1 decimal to 2 decimal in python

I have a list of prices in 1 decimal place and in string format.
I would like to convert each item into a float, change them to two decimal places and append them to a new list.
price = ["9.8", "8.8" ,"10.9", "11.8", "13.9", "18.9"]
newprice = []
I tried this code but it does not work
for i in range(len(price)):
price2= float(price[i])
price= '{0:.3g}'.format(price2)
newprice.append(price)
Most instructions online teach me how to reduce to 2 decimal places, not increase to two decimal places.
You have a few problems here:
you're replacing price (the list) with price (a string) so your loop fails after one iteration
you want the f format specifier to add trailing zeros
You could also make a few improvements, including not using list indexes, using more modern and Pythonic f-strings, and skipping the interim variable price2:
for i in range(len(price)):
newprice.append(f"{float(price[i]):.2f}")
Or you could use a simple list expression:
newprice = [f"{float(n):.2f}" for n in price]
First of all you need to convert the strings to float you can do that with the method float()
Then you add the format to the number with the method format()
You can try the following code:
price = ["9.8", "8.8" ,"10.9", "11.8", "13.9", "18.9"]
price_f = []
for i in price:
new_price_float=format(float(i),'.2f')
price_f.append(new_price_float)
print(price_f)
[float(i) for i in string_prices] is a simple list comprehension that converts your strings to floats
The decimal places of a float is purely for displaying a value so converting from 1 to 2 decimals is not a thing in the language as adding trailing zeros isn't a different value.
string_prices = ["9.8", "8.8" ,"10.9", "11.8", "13.9", "18.9"]
prices = [float(i) for i in string_prices]
for price in prices:
print(f"{price:.2f}")
Since your numbers are already strings, there's no need to convert them to float. Just split at the decimal point, format the right-most piece, and join back together.
price_parts = price[i].split('.')
price_parts[-1] = price_parts[-1][:2].ljust(2, '0')
newprice.append('.'.join(price_parts))
You may want to add some checking to make sure you don't mangle a number that doesn't have a decimal point.

Python decimal.Decimal producing result in scientific notation

I'm dividing a very long into much smaller number. Both are of type decimal.Decimal().
The result is coming out in scientific notation. How do I stop this? I need to print the number in full.
>>> decimal.getcontext().prec
50
>>> val
Decimal('1000000000000000000000000')
>>> units
Decimal('1500000000')
>>> units / val
Decimal('1.5E-15')
The precision is kept internally - you just have to explicitly call for the number of decimal places you want at the point you are exporting your decimal value to a string.
So, if you are going a print, or inserting the value in an HTML template, the first step is to use the string format method (or f-strings), to ensure the number is encompassed:
In [29]: print(f"{units/val:.50f}")
0.00000000000000150000000000000000000000000000000000
Unfortunatelly, the string-format minilanguage has no way to eliminate by itself the redundant zeroes on the right hand side. (the left side can be padded with "0", " ", custom characters, whatever one want, but all the precision after the decimal separator is converted to trailing 0s).
Since finding the least significant non-zero digit is complicated - otherwiser we could use a parameter extracted from the number instead of the "50" for precision in the format expression, the simpler thing is to remove those zeros after formatting take place, with the string .rstrip method:
In [30]: print(f"{units/val:.50f}".rstrip("0"))
0.0000000000000015
In short: this seems to be the only way to go: in all interface points, where the number is leaving the core to an output where it is representd as a string, you format it with an excess of precision with the fixed point notation, and strip out the tailing zeros with f-string:
return template.render(number=f"{number:.50f}".rstrip("0"), ...)
Render the decimal into a formatted string with a float type-indicator {:,f}, and it will display just the right number of digits to express the whole number, regardless of whether it is a very large integer or a very large decimal.
>>> val
Decimal('1000000000000000000000000')
>>> units
Decimal('1500000000')
>>> "{:,f}".format(units / val)
'0.0000000000000015'
# very large decimal integer, formatted as float-type string, appears without any decimal places at all when it has none! Nice!
>>> "{:,f}".format(units * val)
'1,500,000,000,000,000,000,000,000,000,000,000'
You don't need to specify the decimal places. It will display only as many as required to express the number, omitting that trail of useless zeros that appear after the final decimal digit when the decimal is shorter than a fixed format width. And you don't get any decimal places if the number has no fraction part.
Very large numbers are therefore accommodated without having to second guess how large they will be. And you don't have to second guess whether they will be have decimal places either.
Any specified thousands separator {:,f} will likewise only have effect if it turns out that the number is a large integer instead of a long decimal.
Proviso
Decimal(), however, has this idea of significant places, by which it will add trailing zeros if it thinks you want them.
The idea is that it intelligently handles situations where you might be dealing with currency digits such as £ 10.15. To use the example from the documentation:
>>> decimal.Decimal('1.30') + decimal.Decimal('1.20')
Decimal('2.50')
It makes no difference if you format the Decimal() - you still get the trailing zero if the Decimal() deems it to be significant:
>>> "{:,f}".format( decimal.Decimal('1.30') + decimal.Decimal('1.20'))
'2.50'
The same thing happens (perhaps for some good reason?) when you treat thousands and fractions together:
>>> decimal.Decimal(2500) * decimal.Decimal('0.001')
Decimal('2.500')
Remove significant trailing zeros with the Decimal().normalize() method:
>>> (2500 * decimal.Decimal('0.001')).normalize()
Decimal('2.5')

Strict Python formatting for floats

I'm using PYTHON to write to a file where the formatting is very strict. I have 10 available spaces in each column which cannot be exceeded.
I want to write the as many decimals as I can, but if the number is negative, the minus sign must be preferred over the last decimals. Also the period in the float must be counted into the number of available spaces. Numbers should be right trunctated
Example:
Let's say I want to print two numbers
a = 123.4567891011
b = 0.9876543210
Then I would want the result:
123.4567890.98765432
But if I now have the following:
a = -123.1111111111
b = 98765.432101234
c = 567
d = 0.1234
Then I'd want:
-123.1111198765.4321 567.0 0.1234
Would be to nice use exponential notation for high numbers, but not a necessity. I'm unable to find the answer. All I can find is to fix the format to number of significant digits, which really won't help me.
I've tried several methods of the
f.write({0:>10}{1:>10}.format(a,b))
but can't figure it out. Hope you see what I`m looking for.
Okay, so I found a way. I basically convert everything to strings and use:
f.write("{0:>10.10}{1:>10.10}".format(str(a),str(b)))
and so on..

Python, string , integer

I have a string variable:
str1 = '0000120000210000'
I want to convert the string into an integer without losing the first 4 zero characters. In other words, I want the integer variable to also store the first 4 zero digits as part of the integer.
I tried the int() function, but I'm not able to retain the first four digits.
You can use two integers, one to store the width of the number, and the other to store the number itself:
kw = len(s)
k = int(s)
To put the number back together in a string, use format:
print '{:0{width}}'.format(k, width=kw) # prints 0000120000210000
But, in general, you should not store identifiers (such as credit card numbers, student IDs, etc.) as integers, even if they appear to be. Numbers in these contexts should only be used if you need to do arithmetic, and you don't usually do arithmetic with identifiers.
What you want simply cannot be done.. Integer value does not store the leading zero's, because there can be any number of them. So, it can't be said how many to store.
But if you want to print it like that, that can be done by formatting output.
EDIT: -
Added #TimPietzcker's comment from OP to make complete answer: -
You should never store a number as an integer unless you're planning on doing arithmetic with it. In all other cases, they should be stored as strings

Categories

Resources