How to write two dictionaries to CSV? - python

I was wondering how I could iterate over two dictionaries: yin and BL.
I have the following code so far to iterate over yin only:
with open('output.csv', 'wb') as output:
writer = csv.writer(output)
for key, value in yin.iteritems():
writer.writerow([key, value])
yin has values in a dictionary:
{'a': 2248433.0, 'b': 280955.0, 'c': 0.0}
BL has values in a dictionary:
{'a': 27.2, 'b': 57.6, 'c': 0.0}
I want to save it to an excel file so it looks like:
a 2248433.0 27.2
b 280955.0 57.6
c 0.0 0.0
Should I do the following?
with open('output.csv', 'wb') as output:
writer = csv.writer(output)
for key, value, valye in yin.iteritems(), BL.iteritems:
writer.writerow([key, value, value])
I also want the dictionaries to be listed in the same corresponding order in the CSV file. As shown in the table, I want row1: 2248433.0 to correspond to 27.2.
This was the code used to generate dictionaries:
yin = {}
BL = {}
for asdf in glob.glob(ay):
poregn = numpy.genfromtxt(asdf)
btwnROIs = poregn[2:size+2, 0:size]
BLu = poregn[(size*5)+2:(size*5)+size+2, 0:size]
for upmatSC in (list(combinations(range(size_FC),2))):
yin[FC_path1 + '_' + FC_path2 + '_' + str(upmatSC)] = btwnROIs[tuple(upmatSC)]
BL[FC_path1 + '_' + FC_path2 + '_' + str(upmatSC)] = BLu[tuple(upmatSC)]
To explain the code: basically I'm taking two separate matrices and extracting the upper half of each of the matrix and storing these values in two separate dictionaries.

If you have two dictionaries yin and bl, this would be how you would combine the dictionaries in the manner you described and write them to a CSV file:
import csv
yin = {'a': 2248433.0, 'b': 280955.0, 'c': 0.0}
bl = {'a': 27.2, 'b': 57.6, 'c': 0.0}
with open('output.csv', 'w') as output:
cw = csv.writer(output)
for k in yin.keys():
cw.writerow([k, yin[k], bl[k]])

Related

Creating a dictionary of dictionaries from a CSV file

I am trying to create a dictionary of dictionaries in Python from a CSV file, the file looks something like this:
Column 1
Column 2
Column 3
A
flower
12
A
sun
13
B
cloud
14
B
water
34
C
rock
12
And I am trying to get a dictionary of dictionaries that looks like this:
dict = {
'A': {'flower': 12, 'sun': 13},
'B': {'cloud': 14, 'water': 34},
'C': {'rock': 12}
}
The code I tried so far is as follows:
import csv
with open('file.csv', 'r') as csvFile:
rows=csv.reader(csvFile)
d=dict()
for row in rows:
head,tail=row[0], row[1:]
d[head]=dict(zip(tail[0:], tail[1:]))
print(d)
but it's not working well as I am getting this result:
dict = {
'A': {'sun': 13},
'B': {'water': 34},
'C': {'rock': 12}
}
You need to update your d[head] every iteration, not replace it:
import csv
with open('file.csv', 'r') as csvFile:
rows=csv.reader(csvFile)
d=dict()
for row in rows:
head,name,value=row[0], row[1], row[2]
if head not in d:
d[head]= {} # {} is like dict() but faster
d[head][name] = value
print(d)
Or with defaultdict to be more concise:
import csv
from collections import defaultdict
with open('file.csv', 'r') as csvFile:
rows=csv.reader(csvFile)
d = defaultdict(dict)
for row in rows:
head,name,value=row[0], row[1], row[2]
d[head][name] = value
print(d) # or print(dict(d))

Converting a text file to python dictionary - one key and multiple values - with exclusion of one field

I have the following tab-delimited text file:
1 John 27 doctor Chicago
2 Nick 33 engineer Washington
I am trying to convert it into a python dictionary where the key is the NAME and the age, career and address are the values. I would like to exclude the rankings (1, 2).
Code:
myfile = open ("filename", "r")
d = { }
for line in myfile:
x = line.strip().split("\t")
key, values = int(x[0]), x[1:]
d.setdefault(key, []).extend(values)
print(d)
You can convert it to a dict indexed by name with values in tuples instead:
d = {}
with open('filename', 'r') as myfile:
for line in myfile:
_, name, *values = line.strip().split("\t")
d[name] = values
print(d)
With your sample input, this will output:
{'John': ('27', 'doctor', 'Chicago'), 'Nick': ('33', 'engineer', 'Washington')}
You don't explain what difficulties you face.
However, from that sample of tab-delimited text, and you want to have dict like:
{'John': ['27', 'doctor', 'Chicago'], 'Nick': ['33', 'engineer', 'Washington']}
If that's the output you want to reach, then I modified your code a bit.
myfile = open ("filename", "r")
d = { }
for line in myfile:
x = line.strip().split("\t")
key, values = x[1], x[2:]
d.setdefault(key, []).extend(values)
print(d)

Creating dictionary from CSV file, dictionary not containing all values

For the following CSV File:
A,B,C
-----
A1,B1,C1
A1,B2,C2
A2,B3,C3
A2,B4,C4
My dictionary currently looks like this:
{'A1': {'B':'B1', 'C':'C1'}, 'A2': {'B':'B3', 'C':'C3'}
How do I get my dictionary to look like this:
'A1': {'B': ['B1', 'B2'], 'C': ['C1', 'C2']}, 'A2': {'B': ['B3', 'B4'], 'C': ['C3', 'C4']}}
I'm using the following code at the moment:
import csv
reader = csv.DictReader(open('test.csv'))
result = {}
for row in reader:
key = row.pop('A')
if key in result: pass
result[key] = row
print result
You need to create a base case for each key, such that the dictionary inserts the first value as a list. Then you can append values for duplicate keys as they are encountered.
The following code should do what you need:
with open('test.csv') as f:
reader = csv.DictReader(f)
for row in reader:
key = row.pop('A')
if '-' in key:
continue
if key not in result:
new_row = {'B': [row.pop('B')], 'C': [row.pop('C')]}
result[key] = new_row
else:
result[key]['B'].append(row.pop('B'))
result[key]['C'].append(row.pop('C'))
You don't have to use DictReader to achieve this. You can just use regular csv.reader and fill up your own dictionary.
Here is a commented simple solution:
from __future__ import print_function
import csv
csv_fpath = 'test.csv'
# readcsv.py
# You want this:
#{'A1': {'B':['B1','B2'], 'C':['C1','C2']}, 'A2': {'B':['B3','B4'], ..}}
mydict = {}
# newline = '' option is needed as per csv.reader documentation python 3.x
with open(csv_fpath, mode='r') as csvfile:
# A regular csv reader object
myreader = csv.reader(csvfile, delimiter=',')
# Header on first line
hrow = next(myreader)
# # Tagging header names for dictionary keys later
taga, tagb, tagc = hrow[0], hrow[1], hrow[2]
# Skip separator line (delete this line if unnecessary)
next(myreader)
# Reading data and constructing our dictionary
for row in myreader:
if len(row) == 0:
# ignore blank lines
continue
# Each row's key is the first column value
key = row[0]
if key in mydict:
# If an item exists with the given key, that item itself is also a
# dictionary with lists in keys tagb and tagc. So we append to those
# lists the values in second and third columns
mydict[key][tagb].append(row[1])
mydict[key][tagc].append(row[2])
else:
# Note the list constructors, they are important as we are going to
# append them down the iteration
mydict[key] = { tagb: [row[1]]
, tagc: [row[2]]}
print(mydict)
Slightly different approach:
reader = csv.DictReader(open("test.csv"))
result = {}
for row in reader:
if reader.line_num <= 2:
continue
key = row["A"]
for subkey in [k for k in row.keys() if k != "A"]:
if key not in result:
result[key] = {}
if subkey not in result[key]:
result[key][subkey] = []
result[key][subkey].append(row[subkey])
>>> print(result)
{'A2': {'C': ['C3', 'C4'], 'B': ['B3', 'B4']}, 'A1': {'C': ['C1', 'C2'], 'B': ['B1', 'B2']}}

Importing/Exporting a nested dictionary from a CSV file

So I have a CSV file with the data arranged like this:
X,a,1,b,2,c,3
Y,a,1,b,2,c,3,d,4
Z,l,2,m,3
I want to import the CSV to create a nested dictionary so that looks like this.
data = {'X' : {'a' : 1, 'b' : 2, 'c' : 3},
'y' : {'a' : 1, 'b' : 2, 'c' : 3, 'd' : 4},
'Z' : {'l' : 2, 'm' :3}}
After updating the dictionary in the program I wrote (I got that part figured out), I want to be able to export the dictionary onto the same CSV file, overwriting/updating it. However I want it to be in the same format as the previous CSV file so that I can import it again.
I have been playing around with the import and have this so far
import csv
data = {}
with open('userdata.csv', 'r') as f:
reader = csv.reader(f)
for row in reader:
data[row[0]] = {row[i] for i in range(1, len(row))}
But this doesn't work as things are not arranged correctly. Some numbers are subkeys to other numbers, letters are out of place, etc. I haven't even gotten to the export part yet. Any ideas?
Since you're not interested in preserving order, something relatively simple should work:
import csv
# import
data = {}
with open('userdata.csv', 'r') as f:
reader = csv.reader(f)
for row in reader:
a = iter(row[1:])
data[row[0]] = dict(zip(a, a))
# export
with open('userdata_exported.csv', 'w') as f:
writer = csv.writer(f)
for key, values in data.items():
row = [key] + [value for item in values.items() for value in item]
writer.writerow(row)
The latter could be done a little more efficiently by making only a single call to thecsv.writer's writerows()method and passing it a generator expression.
# export2
with open('userdata_exported.csv', 'w') as f:
writer = csv.writer(f)
rows = ([key] + [value for item in values.items() for value in item]
for key, values in data.items())
writer.writerows(rows)
You can use the grouper recipe from itertools:
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return itertools.izip_longest(fillvalue=fillvalue, *args)
This will group your data into the a1/b2/c3 pairs you want. So you can do data[row[0]] = {k: v for k, v in grouper(row[1:], 2)} in your loop.
from collections import defaultdict
data_lines = """X,a,1,b,2,c,3
Y,a,1,b,2,c,3,d,4
Z,l,2,m,3""".splitlines()
data = defaultdict(dict)
for line in data_lines:
# you should probably add guards against invalid data, empty lines etc.
main_key, sep, tail = line.partition(',')
items = [item.strip() for item in tail.split(',')]
items = zip(items[::2], map(int, items[1::2])
# data[main_key] = {key : value for key, value in items}
data[main_key] = dict(items)
print dict(data)
# {'Y': {'a': '1', 'c': '3', 'b': '2', 'd': '4'},
# 'X': {'a': '1', 'c': '3', 'b': '2'},
# 'Z': {'m': '3', 'l': '2'}
# }
I'm lazy, so I might do something like this:
import csv
data = {}
with open('userdata.csv', 'rb') as f:
reader = csv.reader(f)
for row in reader:
data[row[0]] = dict(zip(row[1::2], map(int,row[2::2])))
which works because row[1::2] gives every other element starting at 1, and row[2::2 every other element starting at 2. zip makes a tuple pair of those elements, and then we pass that to dict. This gives
{'Y': {'a': 1, 'c': 3, 'b': 2, 'd': 4},
'X': {'a': 1, 'c': 3, 'b': 2},
'Z': {'m': 3, 'l': 2}}
(Note that I changed your open to use 'rb', which is right for Python 2: if you're using 3, you want 'r', newline='' instead.)

Write dictionary (keys and values) to a csv file

I just want the csv file to look like this:
key,item1,item2,item3
key2,itema,itemB,itemC
and so on
The dictionary has a key and the value is a list of floats.
This is the current code I have to write to the csv file but all it does is write out the key like this: k,e,y,s
Any help is appreciated
with open(outFileName1, 'w') as outfile:
csv_Writer = csv.writer(outfile)
csv_Writer.writerows(dict1)
import csv
dict_data = {'key1': [1, 2, 3], 'key2': [4, 5, 6]}
with open("dict2csv.txt", 'w') as outfile:
csv_writer = csv.writer(outfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)
for k,v in dict_data.items():
csv_writer.writerow([k] + v)
This code will write each key, value pair in your desire format on separate line in csv file.
Without getting into details how CSV works you can easily solve it with something like:
with open("out.txt", 'w') as outfile:
for k,v in dict1.items():
outfile.write(str(k))
for item in v:
outfile.write(","+str(item))
outfile.write(" ")
Your current code iterates the dictionary which yields keys only. Take a look at
import csv
data = {
'key1': ['item1', 'item2'],
'key2': ['item3', 'item4']
}
with open('', 'w') as outfile:
writer = csv.writer(outfile)
for k, v in data.iteritems():
writer.writerow([k] + v)
Notice that it iterates key-value pairs returned by .iteritems(). The key is inserted into a list which is concatenated with the value list.

Categories