Python 3: display long integers in pandas dataframe - python-3.x

I'm trying to set the value of a column in a pandas data frame to some big numbers with a simple line:
df['Capital'] = 58143898.13876611
and it shows in df as format 5.814380e+07. I want it as 58143898.
What I've tried:
df['Capital'] = int(58143898.13876611)
Similar question: How to print all digits of a large number in python?, but it's outdated because I learned from NameError: global name 'long' is not defined that long is replaced by int in python 3. But it still shows 5.814380e+07.
Yet if I only print the following line, it does show as 58143898.
In [2] int(58143898.13876611)
Out[2] 58143898
Please help! Thank you so much in advance :)

You are complaining that pandas represents your number
in floating point rather than integer form.
Coldspeed points out that .astype() can
change a column to some desired type.
To better understand what pandas is doing with your input, look at:
df.dtypes
You want the Capital column to have an integer type.
To avoid the need to monkey about with types later,
you may want to take care to convert inputs to int before constructing the dataframe.
Pandas looks at all values in a column
and chooses a type compatible with the entire set of values.
So e.g. a column containing [1, 2.5, 3]
will force all values to float rather than int.
It's worth noting that missing values can have very noticeable effects on this.
You may want something like:
df2 = df1.dropna()
Certain FP bit patterns are reserved for use as NaN,
but pandas regrettably does not reserve maxint,
nor any other integer value,
to model the notion of missing data.
Accordingly an input like [1, None, 3] will be promoted from int to float.

Related

ValueError: could not convert string to float: '[-0.32062087,0.27050002,......]'

My dataframe has columns where one has list of float values. When I train that column as X_train, I showing cannot string to float or tensorflow float data type.
DataSet:
I tried this:
df['sent_to_vec'].apply(lambda x: float(x))
or nested for loop to convert values in float type; but didn't get executed.
Try passing a string that's really just a floating-point number to the Python float() function:
f1 = float('0.1')
print(f1)
It works.
Try passing a string that's not just a floating-point number, but is instead some sort of array or list representation with multiple numbers separated by other punctuation:
f2 = float('[0.1, 0.2]')
print(f2)
You'll get the same error as you're asking about. That string, '[0.1, 0.2]' is not a representation of a floating-point number that float() can read.
You should look for a function that can read a string like '[0.1, 0.2]'. Can you see the code that wrote the Vectorized data.csv file? (Did you write that code, or that file?)
You'll want to use some function that does the reverse of whatever wrote that column of the file.

Inner workings of map() in a specific parsing situation

I know there are already at least two topics that explain how map() works but I can't seem to understand its workings in a specific case I encountered.
I was working on the following Python exercise:
Write a program that computes the net amount of a bank account based a
transaction log from console input. The transaction log format is
shown as following:
D 100
W 200
D means deposit while W means withdrawal. Suppose the following input
is supplied to the program:
D 300
D 300
W 200
D 100
Then, the output should be:
500
One of the answers offered for this exercise was the following:
total = 0
while True:
s = input().split()
if not s:
break
cm,num = map(str,s)
if cm=='D':
total+=int(num)
if cm=='W':
total-=int(num)
print(total)
Now, I understand that map applies a function (str) to an iterable (s), but what I'm failing to see is how the program identifies what is a number in the s string. I assume str converts each letter/number/etc in a string type, but then how does int(num) know what to pick as a whole number? In other words, how come this code doesn't produce some kind of TypeError or ValueError, because the way I see it, it would try and make an integer of (for example) "D 100"?
first
cm,num = map(str,s)
could be simplified as
cm,num = s
since s is already a list of strings made of 2 elements (if the input is correct). No need to convert strings that are already strings. s is just unpacked into 2 variables.
the way I see it, it would try and make an integer of (for example) "D 100"?
no it cannot, since num is the second parameter of the string.
if input is "D 100", then s is ['D','100'], then cm is 'D' and num is '100'
Then since num represents an integer int(num) is going to convert num to its integer value.
The above code is completely devoid of error checking (number of parameters, parameters "type") but with the correct parameters it works.
and map is completely useless in that particular example too.
The reason is the .split(), statement before in the s = input().split(). This creates a list of the values D and 100 (or ['D', '100']), because the default split character is a space ( ). Then the map function applies the str operation to both 'D' and '100'.
Now the map, function is not really required because both values upon input are automatically of the type str (strings).
The second question is how int(num) knows how to convert a string. This has to do with the second (implicit) argument base. Similar to how .split() has a default argument of the character to split on, so does num have a default argument to convert to.
The full code is similar to int(num, base=10). So as long as num has the values 0-9 and at most 1 ., int can convert it properly to the base 10. For more examples check out built in int.

Data Being Read as Strings instead of Floats

A Pytorch program, which I don't fully understand, produced an output and wrote it into weight.txt. I'm trying to do some further calculations based on this output.
I'd like the output to be interpreted as a list of length 3, each entry of which is a list of floats of length 240.
I use this to load in the data
w=open("weight.txt","r")
weight=[]
for number in w:
weight.append(number)
print(len(weight)) yields 3. So far so good.
But then print(len(weight[0])) yields 6141. That's bad!
On closer inspection, it's because weight[0] is being read character-by-character instead of number-by-number. So for example, print(weight[0][0]) yields - instead of -1.327657848596572876e-01. These numbers are separated by single spaces, which are also being read as characters.
How do I fix this?
Thank you
Edit: I tried making a repair function:
def repair(S):
numbers=[]
num=''
for i in range(len(S)):
if S[i]!=' ':
num+=S[i]
elif S[i]==' ':
num=float(num)
numbers.append(num)
num=''
elif i==len(S)-1:
num+=S[i]
num=float(num)
numbers.append(num)
return numbers
Unfortunately, print(repair('123 456')) returns [123.0] instead of the desired [123.0 456.0].
You haven't told us what your input file looks like, so it's hard to give an exact answer. But, assuming it looks like this:
123 312.8 12
2.5 12.7 32
the following program:
w=open("weight.txt","r")
weight=[]
for line in w:
for n in line.split():
weight.append(float(n))
print weight
will print:
[123.0, 312.8, 12.0, 2.5, 12.7, 32.0]
which is closer to what you're looking for, I presume?
The crux of the issue here is that for number in w in your program simply goes through each line: You have to have another loop to split that line into its constituents and then convert appropriately.

How to convert numpy bytes to float in python3?

My question is similar to this; I tried using genfromtxt but still, it doesn't work. Reads the file as expected but not as floats. Code and File excerpt below
temp = np.genfromtxt('PFRP_12.csv', names=True, skip_header=1, comments="#", delimiter=",", dtype=None)
reads as (b'"0"', b'"0.2241135"', b'"0"', b'"0.01245075"', b'"0"', b'"0"')
"1 _ 1",,,,,
"Time","Force","Stroke","Stress","Strain","Disp."
#"sec","N","mm","MPa","%","mm"
"0","0.2241135","0","0.01245075","0","0"
"0.1","0.2304713","0.0016","0.01280396","0.001066667","0.0016"
"0.2","1.707077","0.004675","0.09483761","0.003116667","0.004675"
I tried with different dtypes (none, str, float, byte), still no success. Thanks!
Edit: As Evert mentioned I tried float also but reads all them as none (nan, nan, nan, nan, nan, nan)
Another solution is to use the converters argument:
np.genfromtxt('inp.txt', names=True, skip_header=1, comments="#",
delimiter=",", dtype=None,
converters=dict((i, lambda s: float(s.decode().strip('"'))) for i in range(6)))
(you'll need to specify a converter for each column).
Side remark Oddly enough, while dtype="U12" or similar should actually produce strings instead of bytes (avoiding the .decode() part), this doesn't seem to work, and results in empty entries.
Here is a fancy, unreadable, functional programming style way of converting your input to the record array you're looking for:
>>> np.core.records.fromarrays(np.asarray([float(y.decode().strip('"')) for x in temp for y in x]).reshape(-1, temp.shape[0]), names=temp.dtype.names, formats=['f'] * len(temp.dtype.names))
or spread out across a few lines:
>>> np.core.records.fromarrays(
... np.asarray(
... [float(y.decode().strip('"')) for x in temp for y in x]
... ).reshape(-1, temp.shape[0]),
... names=temp.dtype.names,
... formats=['f'] * len(temp.dtype.names))
I wouldn't recommend this solution, but sometimes it's fun to hack something like this together.
The issue with your data is a bit more complicated than it may seem.
That is because the numbers in your CSV files really are not numbers: they are explicitly strings, as they have surrounding double quotes.
So, there are 3 steps involved in the conversion to float:
- decode the bytes to Python 3 (unicode) string
- remove (strip) the double quotes from each end of each string
- convert the remaining string to float
This happens inside the double list comprehension, on line 3. It's a double list comprehension, since a rec-array is essentially 2D.
The resulting list, however is 1D. I turn it back into a numpy array (np.asarray) so I can easily reshape to something 2D. That (now plain float) array is then given to np.core.records.fromarrays, with the names taken from the original rec-array, and the formats set for each field to float.

Converting lists of digits stored as strings into integers Python 2.7

Among other things, my project requires the retrieval of distance information from file, converting the data into integers, then adding them to a 128 x 128 matrix.
I am at an impasse while reading the data from line.
I retrieve it with:
distances = []
with open(filename, 'r') as f:
for line in f:
if line[0].isdigit():
distances.extend(line.splitlines())`
This produces a list of strings.
while
int(distances) #does not work
int(distances[0]) # produces the correct integer when called through console
However, the spaces foobar the procedure later on.
An example of list:
['966']['966', '1513' 2410'] # the distance list increases with each additional city. The first item is actually the distance of the second city from the first. The second item is the distance of the third city from the first two.
int(distances[0]) #returns 966 in console. A happy integer for the matrix. However:
int(distances[1]) # returns:
Traceback (most recent call last):
File "", line 1, in
ValueError: invalid literal for int() with base 10: '1513 2410'
I have a slight preference for more pythonic solutions, like list comprehension and the like, but in reality- any and all help is greatly appreciated.
Thank you for your time.
All the information you get from a file is a string at first. You have to parse the information and convert it to different types and formats in your program.
int(distances) does not work because, as you have observed, distances is a list of strings. You cannot convert an entire list to an integer. (What would be the correct answer?)
int(distances[0]) works because you are converting only the first string to an integer, and the string represents an integer so the conversion works.
int(distances[1]) doesn't work because, for some reason, there is no comma between the 2nd and 3rd element of your list, so it is implicitly concatenated to the string 1513 2410. This cannot be converted to an integer because it has a space.
There are a few different solutions that might work for you, but here are a couple of obvious ones for your use case:
distance.extend([int(elem) for elem in line.split()])
This will only work if you are certain every element of the list returned by line.split() can undergo this conversion. You can also do the whole distance list later all at once:
distance = [int(d) for d in distance]
or
distance = map(int, distance)
You should try a few solutions out and implement the one you feel gives you the best combination of working correctly and readability.
My guess is you want to split on all whitespace, rather than newlines. If the file's not large, just read it all in:
distances = map(int, open('file').read().split())
If some of the values aren't numeric:
distances = (int(word) for word in open('file').read().split() if word.isdigit())
If the file is very large, use a generator to avoid reading it all at once:
import itertools
with open('file') as dists:
distances = itertools.chain.from_iterable((int(word) for word in line.split()) for line in dists)

Resources