CSV string to decimal in python list - python

I am using an API that returns what appears to be a CSV string that i need to parse for two decimal numbers and then need to append those numbers to separate lists as decimal numbers (also while ignoring the timestamp at the end):
returned_string_from_API = '0,F,F,1.139520,1.139720,0,0,20160608163132000'
decimal_lowest_in_string = []
decimal_highest_in_string = []
Processing time is a factor in this situation so, what is the fastest way to accomplish this?

Split the string by comma:
>>> string_values = returned_string_from_API.split(',')
>>> string_values
['0', 'F', 'F', '1.139520', '1.139720', '0', '0', '20160608163132000']
Get the values from string:
>>> string_values[3:5]
['1.139520', '1.139720']
Convert to float:
>>> decimal_values = [float(val) for val in string_values[3:5]]
>>> decimal_values
[1.13952, 1.13972]
Get min and max in the appropriate list:
>>> decimal_lowest_in_string = []
>>> decimal_highest_in_string = []
>>> decimal_lowest_in_string.append(min(decimal_values))
>>> decimal_lowest_in_string
[1.13952]
>>> decimal_highest_in_string.append(max(decimal_values))
>>> decimal_highest_in_string
[1.13972]

1) The version which does not rely on cvs
returned_string_from_API = '0,F,F,1.139520,1.139720,0,0,20160608163132000'
def isfloat(value):
try:
float(value)
return True
except ValueError:
return False
float_numbers = filter(isfloat, returned_string_from_API.split(','))
2) try pandas package

Fastest way is to use regular expression. Readability is another issue..
import re
returned_string_from_API = '0,F,F,1.139520,1.139720,0,0,20160608163132000'
decimal_lowest_in_string = []
decimal_highest_in_string = []
re_check = re.compile(r"[0-9]+\.\d*")
m = re_check.findall(returned_string_from_API)
decimal_lowest_in_string.append(min(m))
decimal_highest_in_string.append(max(m))

Related

how can I have commas instead of space in a given set of number

I have a set of number say
s = "39401.99865 7292.4753 8541.03675 6098.54185 106352.218 7300.4485 5699.983 5538.44755 5934.8514 7477.62475 5956.7409 9170.98 9481.5082 6063.4508 9380.92255"
I want to create a list of this number like
my_list = [ 39401.99865, 7292.4753 8541.03675, 6098.54185 , 106352.218 , 7300.4485 ,5699.983 ,5538.44755 5934.8514, 7477.62475, 5956.7409, 9170.98, 9481.5082, 6063.4508 9380.92255]
How can i achieve this? I tried using regular expression but it converted my data into string.
s = '98 9 19'
s = re.sub(r'(?<=\d)\s+(?=\d)', ',', s)
print s
>>> s = "39401.99865 7292.4753 8541.03675 6098.54185 106352.218 7300.4485 5699.983 5538.44755 5934.8514 7477.62475 5956.7409 9170.98 9481.5082 6063.4508 9380.92255"
>>> [float(item) for item in s.split()]
[39401.99865, 7292.4753, 8541.03675, 6098.54185, 106352.218, 7300.4485, 5699.983, 5538.44755, 5934.8514, 7477.62475, 5956.7409, 9170.98, 9481.5082, 6063.4508, 9380.92255]
Or you can use map
>>> map(float, s.split())
[39401.99865, 7292.4753, 8541.03675, 6098.54185, 106352.218, 7300.4485, 5699.983, 5538.44755, 5934.8514, 7477.62475, 5956.7409, 9170.98, 9481.5082, 6063.4508, 9380.92255]

Can this code be rewritten to be more pythonic?

I read in values from a file. I have a line that has this format
size = 'GG|0,WQ|3,EW|8,RE|23'
I want it to be a list of dictionary.
Right now I use this code which works perfect but it seems like there has to be a cleaner way to do it.
>>> size = 'GG|0,WQ|3,EW|8,RE|23'
>>> a = [{i.split('|')[0]:i.split('|')[1]} for i in size.split(',')]
>>> a
[{'GG': '0'}, {'WQ': '3'}, {'EW': '8'}, {'RE': '23'}]
>>>
size = 'GG|0,WQ|3,EW|8,RE|23'
elements = size.split(',')
a = [dict([x.split('|')]) for x in elements]
Perhaps you can use python regex... You can take this further obviously
import re
size = 'GG|0,WQ|3,EW|8,RE|23'
pattern = re.compile('[A-Z][A-Z][|][0-9]+')
my_list = re.findall(pattern, size)
my_dic = [dict([item.split('|')]) for item in my_list]

How to make json decimal round to three digits

I have the following list of list:
x = [["foo",3.923239],["bar",1.22333]]
What I want to do is to convert the numeric value into 3 digits under JSON string.
Yielding
myjsonfinal = "[["foo", 3.923], ["bar", 1.223]]"
I tried this but failed:
import json
print json.dumps(x)
Ideally we'd like this to be fast because need to deal with ~1000 items. Then load to web.
Try round()
import json
x = [["foo",3.923239],["bar",1.22333]]
json.dumps([[s, round(i, 3)] for s, i in x])
#neversaint, Try this:
x = [["foo", 3.923239], ["bar", 1.22333]]
for i, j in enumerate(x):
x[i][1] = round(j[1], 3)
print x
Output:
[['foo', 3.923], ['bar', 1.223]]
Cheers!!

Single integer to multiple integer translation in Python

I'm trying to translate a single integer input to a multiple integer output, and am currently using the transtab function. For instance,
intab3 = "abcdefg"
outtab3 = "ABCDEFG"
trantab3 = maketrans(intab3, outtab3)
is the most basic version of what I'm doing. What I'd like to be able to do is have the input be a single letter and the output be multiple letters. So something like:
intab4 = "abc"
outtab = "yes,no,maybe"
but commas and quotation marks don't work.
It keeps saying :
ValueError: maketrans arguments must have same length
Is there a better function I should be using? Thanks,
You can use a dict here:
>>> dic = {"a":"yes", "b":"no", "c":"maybe"}
>>> strs = "abcd"
>>> "".join(dic.get(x,x) for x in strs)
'yesnomaybed'
In python3, the str.translate method was improved so this just works.
>>> intab4 = "abc"
>>> outtab = "yes,no,maybe"
>>> d = {ord(k): v for k, v in zip(intab4, outtab.split(','))}
>>> print(d)
{97: 'yes', 98: 'no', 99: 'maybe'}
>>> 'abcdefg'.translate(d)
'yesnomaybedefg'

string into a list in Python

I have a str that contains a list of numbers and I want to convert it to a list. Right now I can only get the entire list in the 0th entry of the list, but I want each number to be an element of a list. Does anyone know of an easy way to do this in Python?
for i in in_data.splitlines():
print i.split('Counter32: ')[1].strip().split()
my result not i want
['12576810']\n['1917472404']\n['3104185795']
my data
IF-MIB::ifInOctets.1 = Counter32: 12576810
IF-MIB::ifInOctets.2 = Counter32: 1917472404
IF-MIB::ifInOctets.3 = Counter32: 3104185795
i want result
['12576810','1917472404','3104185795']
Given your data as
>>> data="""IF-MIB::ifInOctets.1 = Counter32: 12576810
IF-MIB::ifInOctets.2 = Counter32: 1917472404
IF-MIB::ifInOctets.3 = Counter32: 3104185795"""
You can use regex where the intent is more clear
>>> import re
>>> [re.findall("\d+$",e)[0] for e in data.splitlines()]
['12576810', '1917472404', '3104185795']
or as #jamylak as pointed out
re.findall("\d+$",data,re.MULTILINE)
Or str.rsplit which will have a edge on performance
>>> [e.rsplit()[-1] for e in data.splitlines()]
['12576810', '1917472404', '3104185795']
You are already quite far. Based on the code you have, try this:
result = []
for i in in_data.splitlines():
result.append(i.split('Counter32: ')[1].strip())
print result
you could also do:
result = [i.split('Counter32: ')[1].strip() for i in in_data.splitlines()]
Then, you can also go and look at what #Abhijit and #KurzedMetal are doing with regular expressions. In general, that would be the way to go, but I really like how you avoided them with a simple split.
My best try with the info you gave:
>>> data = r"['12576810']\n['1917472404']\n['3104185795']"
>>> import re
>>> re.findall("\d+", data)
['12576810', '1917472404', '3104185795']
you could even convert it to int or long if necesary with map()
>>> map(int, re.findall("\d+", data))
[12576810, 1917472404, 3104185795L]
>>> map(long, re.findall("\d+", data))
[12576810L, 1917472404L, 3104185795L]
This is how I'd do it.
data="""IF-MIB::ifInOctets.1 = Counter32: 12576810 ... IF-MIB::ifInOctets.2 = Counter32: 1917472404 ... IF-MIB::ifInOctets.3
= Counter32: 3104185795"""
[ x.split()[-1] for x in data.split("\n") ]
with open('in.txt') as f:
numbers=[y.split()[-1] for y in f]
print(numbers)
['12576810', '1917472404', '3104185795']
or:
with open('in.txt') as f:
numbers=[]
for x in f:
x=x.split()
numbers.append(x[-1])
print(numbers)
['12576810', '1917472404', '3104185795']
result = [(item[(item.rfind(' ')):]).strip() for item in list_of_data]
A variant using list comprehension. Iterator over all line of data, find the last index of a blank, cut down the strip from last found blank position to it's end, strip the resulting string (erase possible blanks) and put the result in a new list.
data = """F-MIB::ifInOctets.1 = Counter32: 12576810
IF-MIB::ifInOctets.2 = Counter32: 1917472404
IF-MIB::ifInOctets.3 = Counter32: 3104185795"""
result = [ (item[(item.rfind(' ')):]).strip() for item in data.splitlines()]
print result
Result:
['12576810', '1917472404', '3104185795']

Categories