1

I have a csv file where I want to query results based on the first row and first column. Given a csv that looks like:

subj_id, Sample1, Sample2, Sample3
XXX, 1, 2, 3
YYY, 4, 5, 6
ZZZ, 7, 8, 9

I would like to use the subj_id and SampleN to query the value. For example:

dct['XXX']['Sample1'] = 1, dct['YYY']['Sample2'] = 5

I have tried using csv.DictReader, but without success. How can I create a dictionary like the above? (Note: I am using python 3.6, as I see that DictReader is slightly different depending on the python version.)

My attempt was based on this SO question, where the start was:

import csv
from collections import defaultdict

dct = defaultdict(dict)

with open('toy_out_test_results.csv', 'r') as csv_file:
    for row in csv.DictReader(csv_file, fieldnames=['subj_id','Sample1','Sample2','Sample3']):
        dct[row['subj_id']][row['???']] =     

but I ran into a roadblock here.

Adam_G
  • 7,337
  • 20
  • 86
  • 148
  • 1
    Sorry about that. I added my minimal example, which I couldn't even flesh out. – Adam_G Sep 11 '20 at 15:16
  • Thanks, that's perfect. Is the whitespace in your CSV intentional or do you want to trim all the fields? – ggorlen Sep 11 '20 at 15:24
  • 1
    Ah, not intentional at all. My actual csv doesn't have it. – Adam_G Sep 11 '20 at 15:26
  • Does this answer your question? [Creating a dictionary from a CSV file](https://stackoverflow.com/questions/14091387/creating-a-dictionary-from-a-csv-file) – ggorlen Sep 11 '20 at 15:40

1 Answers1

1

You can assign the row dictionary to the dct dict based on the row['subj_id'] value which you can pop out of the row:

import csv

dct = {}

with open('toy_out_test_results.csv', 'r') as csv_file:
    for row in csv.DictReader(csv_file):
        dct[row.pop('subj_id')] = row

print(dct['XXX']['Sample1']) # => '1'

This assumes a CSV without extra whitespace:

subj_id,Sample1,Sample2,Sample3
XXX,1,2,3
YYY,4,5,6
ZZZ,7,8,9

Beware that duplicate subj_ids will be overwritten with the last seen.

ggorlen
  • 44,755
  • 7
  • 76
  • 106