简体   繁体   中英

Print all rows related to minimum values from another column based on distinct values of a specific column from csv file using python csv

I have a CSV file with following structure:

Id,User,P_Name,P_Code,Rate

1,U1,P1,1234,21.5

2,U1,P2,7483,20

3,U1,P3,8945,29.5

4,U2,P1,1234,80

5,U2,P2,7483,23.5

6,U2,P3,8945,30

7,U3,P1,1234,15

8,U3,P2,7483,27.3

9,U3,P3,8945,,29.7

I want to print complete rows for minimum value of each product. For instance, here it would be:

7,U3,P1,1234,15

2,U1,P2,7483,20

3,U1,P3,8945,29.5

I am new to python and unable to proceed after this:

import csv
with open('sample.csv', 'rb') as csvfile:
        filereader = csv.reader(csvfile, delimiter=',', quotechar='|')
        headers=next(filereader)
        data = []
        for row in filereader:
                data.append(row[2])
        print (data)

Here, I am getting a list of P_Name values and unable to figure out how to get minimum value of each distinct product.

First append the whole CVS row, not just the third items of the row (like row[2] )

import csv
with open('sample.csv', 'rb') as csvfile:
    filereader = csv.reader(csvfile, delimiter=',', quotechar='|')
    headers=next(filereader)
    data = []
    for row in filereader:
            data.append(row)
    print (data)

Then build a dict that use P_name as a key, with the whole row as value. The dicts thus stores the whole row, with row[2] as key. Then iter over each row, replace the current dict value with a new, if a lower price is found.

filter = {}
for item in data:
   if item[2] not in filter.keys():     #First if dict already has an entry in dict
           filter[item[2]] = item       #if no entry ad entry
   elif item[4] < filter[item[2]][4]:   #if entry compare between entry in dicts and cvs line. 
                                        #Both refer to [4] so booth compare the rate of the CVS column
           filter[item[2]] = item

And to print your values.

 for item in filter.keys():
      print item,' : ',filter[item]

Per your second remarks, then is it better to add extra info to the values. You could opt for a list that holds data for price in index 0 price[0] and users in index 1, price[1]

filter = {}
for item in data:
   if item[2] not in filter.keys():     #First if dict already has an entry in dict
           filter[item[2]] = [item[4], [item[1]]       #if no entry ad entry, the dict value is a list.
 #Filter Dict Value explained ..
 #Index 0 stores the the price of the product
 #Index 1 stores a list of users that have the product at this value. 

   elif   item[4] == filer[item[2]][0]:                #price is identical add another user to the dict[product][second slot of list]
              filter[item[2]][1].append(item[1])       #filter[productCode][second index] APPEND [New user ]



   elif item[4] < filter[item[2]][0]:   

#If a lower product rate has been found, then reset the value of the dict. 
#And store new lower price, with it's corresponding user.                                       
           filter[item[2]] = [item[4], [item[1]]

Thanks for the response. I had modified your code a bit to make it a bit simpler.

filter = {} for item in data: if item[2] not in filter.keys():
filter[item[2]] = item
elif item[4] == filter[item[2]][4]:
filter[item[2]].append(item) elif item[4] < filter[item[2]][4]:
filter[item[2]] = item

Although, it works fine. However, I am facing some issues with formatting of the result after updating row 5 (post header) in the csv file from

5,U2,P2,7483,23.5 

to

5,U2,P2,7483,20

And then printed results using following code:

 for item in filter.keys():
                print filter[item]

Results are as follows:

['2', 'U1', 'P2', '7483', '20', ['5', 'U2', 'P2', '7483', '20']]
['3', 'U1', 'P3', '8945', '29.5']
['7', 'U3', 'P1', '1234', '15']

whereas if in case there are two users paying identical price for a particular product then instead of appending those details along with previous user, I want to display it as a separate entry and in similar format as csv file (without brackets and quotes), like:

2,U1,P2,7483,20 
5,U2,P2,7483,20
3,U1,P3,8945,29.5
7,U3,P1,1234,15

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM