muad-dweeb
muad-dweeb

Reputation: 1155

Is there a way to export data from a Counter object to a CSV file?

I have created Counter objects containing characters and the number of times those characters occur in a given file. I would like to be able to display these data sets in a more readable and useful format, such as CSV.

Here's a sample Counter object:

Counter({u' ': 10304, u'0': 1630, u'\n': 1516, u'*': 1196, u'.': 1026, u'1': 1003, u'A': 991, u'E': 954, u'9': 937, u'S': 845, u'R': 834, u'T': 781, u'O': 745, u'2': 736, u'F': 726, u'4': 653, u'N': 596, u'C': 575, u'3': 558, u'L': 557, u'5': 535, u'I': 532, u'8': 481, u'7': 456, u'6': 410, u'P': 400, u'\t': 388, u'G': 377, u'M': 327, u'Y': 326, u'D': 323, u'e': 305, u'B': 292, u'U': 272, u'H': 256, u'a': 224, u'r': 216, u'W': 208, u'l': 178, u'/': 174, u'K': 167, u'i': 164, u'V': 160, u'o': 155, u't': 155, u'X': 153, u'b': 134, u'-': 132, u'n': 130, u's': 112, u'$': 97, u'@': 96, u':': 89, u'g': 85, u'c': 84, u'Q': 75, u'v': 75, u'u': 71, u'd': 69, u'+': 68, u'#': 63, u'y': 59, u'h': 58, u'm': 52, u'p': 42, u'Z': 36, u'f': 32, u')': 26, u'(': 26, u'w': 22, u'%': 21, u',': 21, u'!': 17, u'=': 16, u'k': 13, u'J': 12, u'&': 10, u'x': 7, u"'": 6, u'q': 6, u'z': 2})

It is similar to a dictionary, but I can't figure out how to properly extract the key, value pairs, let alone write them to a CSV file. The following code creates a CSV file and writes the counts to the characters column while not writing the characters to the file at all. This is as far as I have gotten.

with open('{}.csv'.format(str(counter_object)), 'w') as csvfile:
    fieldnames = ['character', 'count']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

    writer.writeheader()
    for dictionary in counter_object:
        for character, count in dictionary.items():
            writer.writerow(dict(character=count))

Is there any protocol for dealing specifically with Counter objects in such a way?

EDIT

I saw this post here, but trying that solution results in an error:

    for key, count in <counter_object>.items():
AttributeError: 'tuple' object has no attribute 'items'

Upvotes: 1

Views: 1666

Answers (2)

Harry Harrison
Harry Harrison

Reputation: 591

The issue is the way you create your dict, try something like this instead:

writer.writerow({'character':character,'count':count})
#or
writer.writerow(dict(character=character,count=count))

The reason your existing code causes a problem is evident if you run the following code, you'll see something like this:

>>> print(dict(character=count))
{'character': 4 }

You're creating a dict with a single Key value pair with the key as 'character' and the value as the count.

EDIT:

You also have an issue with your loop, rather than two nested for loops, you can try this:

for character, count in counter_object.items():

Upvotes: 0

tzaman
tzaman

Reputation: 47790

A DictWriter expects you to pass it each row as a dictionary object where the keys are the same as the fieldnames you constructed it with. You could either do that:

writer.writerows({'character': k, 'count': v} for k, v in counter_object.items())

or simply use a regular writer instead of a dictwriter and just pass it items() directly:

writer = csv.writer(csvfile)
writer.writerow(fieldnames)   # write header explicitly
writer.writerows(counter_object.items())  # no transformation needed

Note that you don't need for loops in either case, you can just use a list comprehension in combination with the writerows() method.

Upvotes: 0

Related Questions