Python pandas shows all ints in csv as floats - python

I want to verify that values in a CSV are integers and report an error if they are not. Being an amateur, I thought I had it figured out if the user entered '8k' or whatever as a value by using this:
try:
int(value)
except ValueError:
print("No Deal, Howie!")
I completely overlooked the possibility that a user can enter 8.8, which is unacceptable as well. Unfortunately, I can't use:
if type(value) == int
because pandas dataframe turns all the ints in my CSV into numpy.float64. What can I do about this?

Here's a pretty safe method that will capture a bunch of different integer types.
import numpy as np
def num_is_int(x):
if isinstance(x, (int, np.integer)):
return True
else:
try:
return x.is_integer()
except AttributeError:
return False
num_is_int(7)
True
num_is_int(7.0)
True
num_is_int(np.int16(7))
True
num_is_int(7.1)
False
num_is_int('7')
False
num_is_int(None)
False

You can use int() like this:
if value == int(value)

To check if the value is an integer you can convert it into a string, use .split() method and search for zeros.
An example:
A=5.000006
print(A)
B=str(A).split(sep='.')
print(B)
print(B[1])
integer=1
for b in B[1]:#B[1] is the decimal part of A
if b!='0':
integer=0
If integer=0, this is not an integer,
If integer=1 this is an integer.

I would use Python's builtin isinstance function. Like this:
if not isinstance(value, int):
print("No Deal, Howie!")

Related

Python cannot ignore str when input is int()

SO I have a program where the input is in an int, but when the user enters a str, the program crashes. I want the program to ignore any str that it can't convert to an int. I tried declaring a variable that said type(input). Then, I added an if statement:
if (variable) == str:
print(oops)
Remember I declared the input as an int. So I don't know.
Thank you.
You can use exceptions for this. You get a Value Error when you try to convert a string input to int. By enclosing it in a try clause here, it is telling that if a Value Error arises, you can ignore it. For now I've used the pass statement, but if there's something else you want to do if the input is a string, you can add it there.
try:
x = input()
value = int(x)
print(value)
except ValueError:
pass
You can use try-except to handle the case.
try:
value = int(input())
except ValueError:
print("Input is not an int type")
pass
In python you can call isinstance() on the variable passing the datatype you want to check for-
sent = 'your_string'
num = 24
isinstance(sent, int) # returns False
isinstance(num, int) # returns True
isinstance(sent, str) # returns True
isinstance(num, str) # returns False
Applicable with other data types too!
So a simple-
if not isinstance(str, int):
print('Only integer values accepted')
if my_input.isdigit():
int(my_input)
# your code goes here
else:
print('oops')
exit() # maybe you like to exit
You could do something like
input_number = input("Enter your number")
if type(eval(input_number)) == int:
#Do stuff
else:
print('Sorry that is an invalid input')
I also noticed you said
Remeber I declared the input as an int
Python is not statically typed, so you don't have to declare a variable as a certain data type, and along with that even if you do, their type can still be changed.
You can use str.isnumeric() to check if input is of int type or not. THis is better than using try..except
input_number = input("enter a number: ")
if input_number.isnumeric():
input_number = int(input_number)
# do magic

How to automatically determine type for user input?

I want to make a simple math function that takes user input, yet allows the user to not input an integer/float. I quickly learned Python does not identify type by default. Quick Google search shows using literal_eval, but it returns with ValueError: malformed string if a string is the input. This is what I have so far:
from ast import literal_eval
def distance_from_zero(x):
if type(x) == int or type(x) == float:
return abs(x)
else:
return "Not possible"
x = literal_eval(raw_input("Please try to enter a number "))
print distance_from_zero(x)
Just answer your query why ValueError: malformed string occurred if you read the literal_eval doc :
Safely evaluate an expression node or a string containing a Python
expression. The string or node provided may only consist of the
following Python literal structures: strings, numbers, tuples, lists,
dicts, booleans, and None.
so string should be inclosed by "" as used to write in editor like s = "string"
raw_input takes the input and convert to string data type so i have tried this and able to convert using literal_eval
>>> x=raw_input()
string
>>> x= "\""+x+"\"" # concatenating the "" to string
>>> literal_eval(x)
'string'
>>>
Like you mentioned you will get malformed string error (ValueError) if you get input like ast.literal_eval('c1'). You will also get SyntaxError if you do something like ast.literal_eval('1c'). You will want get the input data and then pass it to literal_eval. You can then catch both of these exceptions, and then return your 'Not Possible'.
from ast import literal_eval
def distance_from_zero(x):
try:
return abs(literal_eval(x))
except (SyntaxError, ValueError):
return 'Not possible'
x = raw_input("Please try to enter a number ")
print distance_from_zero(x)

How to check data type of variable?

I want to check the type of input, check if data is float or int.
# type of inData will be String
inData = input("Enter Data")
if inData.isdigit():
print("Integer")
This will check if the inData is an integer, but this won't check for float type.
Any suggestions?
As I understand it, you want to check whether inData can be converted to float.
You can do that like this:
def isFloat(x):
try:
float(x) #tries to convert x to float. raises an exception if unsuccessful
except ValueError:
return False # return false if exception was raised
return True
if isFloat(inData):
print("Float")
For understanding exceptions have a look at this
You can use the type() builtin to see the type of an object.
For example, type(inData) is float will return True if inData is a float.

Conditional string representation based on variable type

I would like to create a string representation of a datetime object that could contain a None value. So far, I came up with a solution, but I was looking at a better/cleaner way of doing it.
Let's say I have the following two variables:
import datetime as dt
a = None
b = dt.datetime(2017, 11, 30)
def str_format(str):
return '{:%Y-%m-%d}'.format(str)
The following would return a formatted string:
str_format(b)
'2017-11-30'
But the following would return an error:
str_format(a)
TypeError: unsupported format string passed to NoneType.__format__
So far I can up with the following solution:
def str_format(str):
if isinstance(str, type(None)) is False:
return '{:%Y-%m-%d}'.format(str)
else:
return '{}'.format(str)
str_format(a)
'None'
str_format(b)
'2017-11-30'
However, I was looking at a more efficient/cleaner way of writing the function.
Often times these types of things are wrapped in a try/except
def str_format(str):
try:
return '{:%Y-%m-%d}'.format(str)
except TypeError:
# unrecognized type, return blank or whatever you want to return
return ''
The answer on this question explains why you typically use try/except instead of a conditional check fairly well.
your function is overcomplex. None is a singleton, so the pythonic way of testing against it is just is None.
Just do it in one line with a ternary expression:
def str_format(s):
return str(s) if s is None else '{:%Y-%m-%d}'.format(s)
or to return a default date (ex: 1/1/2010) if None is passed:
def str_format(s):
return '{:%Y-%m-%d}'.format(s or dt.datetime(2010, 1, 1))
as a side note don't use str as a variable name as it is the python string type.

String checking on multiple types

I have a variable containing a string (extracted from a XML feed). The string value can be of type integer, date or string. I need to convert it from string to given data type. I am doing it this way but it is a little bit ugly so I am asking if there is a better technique. If I would checking for more types, I will end with very nested try - except blocks.
def normalize_availability(self, value):
"""
Normalize the availability date.
"""
try:
val = int(value)
except ValueError:
try:
val = datetime.datetime.strptime(value, '%Y-%m-%d')
except (ValueError, TypeError):
# Here could be another try - except block if more types needed
val = value
Thanks!
Use a handy helper function.
def tryconvert(value, default, *types):
"""Converts value to one of the given types. The first type that succeeds is
used, so the types should be specified from most-picky to least-picky (e.g.
int before float). The default is returned if all types fail to convert
the value. The types needn't actually be types (any callable that takes a
single argument and returns a value will work)."""
value = value.strip()
for t in types:
try:
return t(value)
except (ValueError, TypeError):
pass
return default
Then write a function for parsing the date/time:
def parsedatetime(value, format="%Y-%m-%d")
return datetime.datetime.striptime(value, format)
Now put 'em together:
value = tryconvert(value, None, parsedatetime, int)
The right way would be to know from the xml what type each should be. This would prevent things that happen to be numeric strings from ending up as an int, etc. But assuming that isn't possible.
for int type I prefer
if value.isdigit():
val = int(value)
for the date, the only other way I can think of would be splitting it and looking at the parts, which would be messier then just letting the strptime raise an exception.
def normalize_availability(value):
"""
Normalize the availability date.
"""
val = value
try:
val = datetime.datetime.strptime(value, '%Y-%m-%d')
except (ValueError):
if value.strip(" -+").isdigit():
val = int(value)
return val

Categories