Miminum of each list in a list of lists - python

I was wondering if it was possible to get the minimum value of each list in a list of lists.
import csv
data=[]
file=input ("Enter file name: ")
with open(file,"r") as f:
reader = csv.reader(f, delimiter=';')
for row in reader:
data.append(row)
print(data)
Output:
[['13.25', '12.97', '13.12', '13.47', '13.44', '13.09', '12.86', '12.78', '12.91', '12.93', '12.91', '13.11'], ['12.92', '13.42', '13.58', '13.7', '13.62', '13.7', '13.31', '12.86', '12.59', '12.81', '13.46', '12.9'], ['13.39', '13.5', '13.29', '13.26', '13.38', '13.45', '13.46', '11.95', '', '12.57', '13.22', '12.88'], ['12.48', '13.76', '13.7', '13.77', '13.08', '13.48', '13.25', '12.31', '12.56', '12.56', '12.95', '13.38'], ['12.52', '14.07', '14.46', '14.13', '13.98', '14.07', '13.92', '12.7', '13.01', '12.79', '13', '13.13']]

The minimum value of a list of lists of numbers can be achieved with a simple call to map:
numbers = [[1,3,6], [6,7,2], [0,-4]]
minimum_numbers = map(min, numbers)
print minimum_numbers
# This prints: [1, 2, -4]
This will return a list where min was called for each element in the "outer list" numbers.

Python has a min function that can be called on lists to get the lowest value. You can loop through your data list and call min() on each list contained.
for list in data:
print(min(list))
Given your output this would return:
12.78
12.59
12.31
12.52
The third one is blank because the array has an empty value in it.
If you want to remove empty strings you can use filter()
for list in data:
list = filter(None, list)
print(min(list))
This outputs
12.78
12.59
11.95
12.31
12.52
Also I noticed all the values are floats, you can also convert them before checking min value so you're not comparing strings.
for list in data:
list = filter(None, list)
list = [float(i) for i in list]
print(min(list))

First you'll need to convert each of the items to floats. Do this when you read the data in:
import csv
data=[]
file=input ("Enter file name: ")
with open(file,"r") as f:
reader = csv.reader(f, delimiter=';')
for row in reader:
data.append([float(x) for x in row if x]) # converts values to floats, ignores empty ones
print(data)
Once your done with that, just call min() on each list:
>>> [min(x) for x in data]
[12.78, 12.59, 11.95, 12.31, 12.52]
You can shorten your reading loop to this:
>>> with open(file, "r") as f:
... reader = csv.reader(f, delimiter=";")
... data = [[float(x) for x in row] for row in reader]
>>> print([min(x) for x in data])

I think that you should use Emil Vikström's answer, but since you have control over your loading code you can prevent unnecessary storing of data and simply do:
with open(file,"r") as f:
reader = csv.reader(f, delimiter=';')
for row in reader:
data.append(min(map(float, row)))

I would use the map function...
listOfLists = [ [2, 3, 1], [5, 7, 8], .... ]
minValues = map(lambda x: min(x), listOfLists)
Result:
minValues = [1, 5, ...]

Related

Reading values from file and storing them in dictionary

I want to write a function read_file() to read the values in the file and store the data in the a dictionary. The dictionary will look something like this:
product = {'d01':['pencil', 5], 'd02':['highlighter', 7], 'd03':['sharpener', 10]....}
What the items in the file looks like:
input:
d={}
file=r"C:\Users\Public\Documents\Folder\products.dat"
with open(file,'r') as f:
for items in f:
print(items)
results:
d01,pencil,5
d02,highlighter,7
d03,sharpener, 10
d04,pen,3
Here are my codes:
def read_file():
d={}
file=r"C:\Users\Public\Documents\Folder\products.dat"
with open(file,'r') as f:
for items in f:
stuff = items.split(",")
quantity = int(stuff[2].rstrip())
a = stuff[0]
b = [stuff[1], quantity]
d = {a:b}
print(d)
read_file()
Currently results I got:
{'d01': ['pencil', 5]}
{'d02': ['highlighter', 7]}
{'d03': ['sharpener', 10]}
{'d04': ['pen', 3]}
How do I achieve the above results?
Don't create a new dictionary for each line, add an element to the same dictonary.
Change
d = {a:b}
to
d[a] = b
And put print(d) after the loop is done, not inside the loop.
To read and parse a csv file into a dictionary of lists, using the first item on each line as a key and the remaining items on each line as a value list:
import csv
def parse(csvfilename):
dic = {}
with open(csvfilename, "r") as csvfile
csvreader = csv.reader(csvfile, skipinitialspace=True)
for row in csvreader:
table[row[0]] = row[1:]
return dic

How to sum a row of values from a text file using Python

I have rows of values in a text file which looks like this:
2,3,4,2
4,5,6,3
2,3,4,1
I want to be able to sum them in rows:
Eg,
row1 = 11
row2 = 18
row3 = 10
I have tried to add all the lines in a multi dimensional array, however I am having difficulties. I have tried the codes below:
allVotes=[]
fo=open('Votes.txt','r')
for line in fo:
line=line.strip()
parts=line.split(',')
eachLine=int(line)
allVotes.append(eachLine)
print(allVotes)
However, each line is not an integer. Any other ways to solve this?
To get it into a 2-D array try this
all_values = []
with open('Votes.txt', 'rt') as file:
for line in file:
line = list(map(int, string.split(",")))
all_values.append(line)
Or you could do something like this to get the sum of each line in a 1d array.
def get_results(filename):
def sum_line(line):
return sum(map(int, line.split(",")))
with open(filename, 'rt') as file:
return [sum_line(line) for line in file]
You can not convert a list of strings to list of integers with int() call on that list, you need to convert each value separately since int() function accepts strings only.
To do that you can use list comprehensions or map function:
# List comprehension
eachLine = [int(s) for s in line]
# using map function
eachLine = list(map(int, line))
You can call sum() on these lists to get the sums. So, in your case results can be achieved by the following code:
fo=open('Votes.txt','r')
for line in fo:
vote_sums = sum([int(s) for s in line.strip().split(',')])
print(vote_sums)
Try this one:
fo=open('rank.txt','r')
for line in fo:
l=list(map(int,line.split(",")))
sm=sum(l[0:len(l)])
print (sm)
sum(map(lambda x: int(x), raw_input().split(',')))
Using pandas we can do this in a single-row operation.
s = u"""2,3,4,2
4,5,6,3
2,3,4,1"""
import io
import pandas as pd
l = pd.read_csv(io.StringIO(s),header=None).sum(axis=1).tolist()
#l = pd.read_csv("path/to/file.csv",header=None).sum(axis=1).tolist()
l returns:
[11, 18, 10]
With pandas we can also export to dictionaries:
df = pd.read_csv(io.StringIO(s),header=None).sum(axis=1)
df.index = ("row {}".format(i+1) for i in range(len(df)))
d = df.to_dict()
d returns
{'row 1': 11, 'row 2': 18, 'row 3': 10}

Python list write to CSV without the square brackets

I have this main function:
def main():
subprocess.call("cls", shell=True)
ipList,hostList,manfList,masterList,temp = [],[],[],[],[]
ipList,hostList,manfList, = getIPs(),getHosts(),getManfs()
entries = len(hostList)
i = 0
for i in xrange(i, entries):
temp = [[hostList[i]],[manfList[i]],[ipList[i]]]
masterList.append(temp)
with open("output.csv", "wb") as f:
writer = csv.writer(f, delimiter=',')
writer.writerows(masterList)
My current output is that it successfully writes to CSV but my objective is to remove the square brackets.
I tried using .join() method however I understand that it only takes single lists and not nested lists.
How can I achieve this given that I'm using a 3 dimensional list? Note, I intend to add more columns of data in the future.
Edit:
My current output for 1 row is similar to:
['Name1,'] ['Brand,'] ['1.1.1.1,']
I would like it to be:
Name1, Brand, 1.1.1.1,
Try to remove bracket for values in temp while creating masterList, because it will be nested list. So, the code should be:
def main():
subprocess.call("cls", shell=True)
ipList,hostList,manfList,masterList,temp = [],[],[],[],[]
ipList,hostList,manfList, = getIPs(),getHosts(),getManfs()
entries = len(hostList)
i = 0
for i in xrange(i, entries):
temp = [hostList[i], manfList[i], ipList[i]]
masterList.append(temp)
with open("output.csv", "wb") as f:
writer = csv.writer(f, delimiter=',')
writer.writerows(masterList)
What you could do is strip a string of the data maybe?
import string
writer.writerows(str(masterList).translate(string.maketrans('', ''), '[]\'')
E.g.
>>> import string
>>> temp = [['1.1.1'], ['Name1'], ['123']]
>>> str(temp).translate(string.maketrans('', ''), '[]\'')
'1.1.1, Name1, 123'
In Python 3.6:
>>> temp = [['1.1.1'], ['Name1'], ['123']]
>>> str(temp).translate({ord('['): '', ord(']'): '', ord('\''): ''})
'1.1.1, Name1, 123'
Try to change this:
temp = [[hostList[i]],[manfList[i]],[ipList[i]]]
to this:
temp = [hostList[i],manfList[i],ipList[i]]
I agree with the answers above, about the brackets removal, however if this is crucial to you for some reason, here is a function that takes a list as an input and returns you a csv row acceptable list.
def output_list(masterList):
output = []
for item in masterList:
if isinstance(item,list): #if item is a list
for i in output_list(item): #call this function on it and append its each value separately. If it has more lists in it this function will call itself again
output.append(i)
else:
output.append(item)
return output
You can use it in the line masterList.append(temp) as masterList.append(output_list(temp)), or even like this:
#in the end
with open("output.csv", "wb") as f:
writer = csv.writer(f, delimiter=',')
for i in masterList:
writer.writerow(output_list(i))

changing given text to list of lists

I have the following text in a given file:
1234,A,7.99,10.3,12.8,101,0.11843,0.27276,0.30101
87635,B,19.69,21.25,130,1203,0.1096,0.1599,0.1974
First, I want to get rid of the 1234 and 87635 in the front, and I also want to change A into the integer "1" and B into the integer "0".
This is my code:
def convert(file):
data = open(file, 'r')
list1 = []
for line in data:
line_data = line.strip().split(',')
if line_data[0] == "B":
line_data[0] = 0
else:
line_data[0] = 1
for i in range(len(line)):
datalist.append(line)
list1 = np.array(list1), float
data.close()
return list1
This is the output I want:
[[1234,A,7.99,10.3,12.8,101,0.11843,0.27276,0.30101], [87635,B,19.69,21.25,130,1203,0.1096,0.1599,0.1974]]
The output I'm currently getting is a list of strings, instead of the list of lists.
You are getting a list of strings , because you are appending to the list as -
datalist.append(line)
This appends the original line , not the changed line_data . Also, all the elements in line_data would still be strings (expect for the first element) , as you are never converting them to int.
This easiest here would be to use csv module , parse the file as csv and then pop the first element from each row that is returned and then change the second element (now first element after removing , as you want). Example -
def convert(file):
import csv
lst = []
with open('<filename>','r') as f:
reader = csv.reader(f)
for row in reader:
row.pop(0)
if row[0] == 'B':
row[0] = 0
else:
row[0] = 1
lst.append(list(map(float, row)))
return lst
Example/Demo -
My a.csv -
1234,A,7.99,10.3,12.8,101,0.11843,0.27276,0.30101
87635,B,19.69,21.25,130,1203,0.1096,0.1599,0.1974
Code and Result -
>>> import csv
>>> with open('a.csv','r') as f:
... reader = csv.reader(f)
... lst = []
... for row in reader:
... row.pop(0)
... if row[0] == 'B':
... row[0] = 0
... else:
... row[0] = 1
... lst.append(list(map(float, row)))
...
'1234'
'87635'
>>> lst
[[1.0, 7.99, 10.3, 12.8, 101.0, 0.11843, 0.27276, 0.30101], [0.0, 19.69, 21.25, 130.0, 1203.0, 0.1096, 0.1599, 0.1974]]

How to convert values to float and assign them to a dictionary in Python?

I am trying to read content from a CSV file and store them in a dictionary.
Each row of my CSV file is formatted as:
'Node_001', '0.0067', '0.2456', '0.7896', ......
The first element will be used as key in dictionary, while the rest part are values.
Since these values are generated by equations in excel, I don't think there are anything wrong with the format itself.
Here is my code:
with open(path, "rb") as file:
reader = csv.reader(file)
my_dictionary = dict()
for row in reader:
node_id = row[0]
temp_values = row[1:]
[float(x) for x in temp_values]
my_dictionary[node_id] = temp_values
print isinstance(temp_values[0], float)
I print the first element of the numeric part of my rows to exam if they are converted to float. However, all I got is False.
So, may I know what is wrong with my code?
Thanks.
The line [float(x) for x in temp_values] does not modify temp_values but creates a new list. you have to reassign it like:
with open(path, "rb") as file:
reader = csv.reader(file)
my_dictionary = dict()
for row in reader:
node_id = row[0]
temp_values = row[1:]
temp_values = [float(x) for x in temp_values]
my_dictionary[node_id] = temp_values
print isinstance(temp_values[0], float)
This chunk of code:
for row in reader:
node_id = row[0]
temp_values = row[1:]
[float(x) for x in temp_values]
my_dictionary[node_id] = temp_values
print isinstance(temp_values[0], float)
creates a list of float values with this line:
[float(x) for x in temp_values]
...but since it's not assigned to anything, it goes away immediately.
changing that line to
temp_values = [float(x) for x in temp_values]
creates the converted list and assigns it to temp_values so the rest of your code can use those values.
Try this for a change, assuming you only have unique keys in your file:
with open(path, 'r') as f:
reader = csv.reader(f)
d = {r[0]:map(float, r[1:]) for r in reader}
print(d)
You can also stick with a list comprehension with this:
with open(path, 'r') as f:
reader = csv.reader(f)
d = {r[0]: [float(i) for i in r[1:]] for r in reader}
You are not saving the conversion:
temp_values = [float(x) for x in temp_values]
If you replace your list comprehension with this one, your code should work.

Categories