2

我是一个每天都在与 Python 苦苦挣扎的初学者。我有一个大型数据集,第二列中有动物名称。我有一个程序可以按每个动物的名称来计算每个动物的数量(每行有 1 个动物名称和 1 个“计数”数据)。我正在尝试获取使用 Python 获得的计数数据的总和,但我无法做到这一点。我到目前为止的代码是:

import csv, collections

reader=csv.reader(open('C:\Users\Owl\Data.txt','rb'), delimiter='\t')

counts=collections.Counter()

for line in reader:
   Name=line[1]
   counts[Name]+=1

for (Name, count) in sorted(counts.iteritems()):
   Output=list('%s' % count) #Make output string to a list
   Sum=sum(Output) # Sum function requires a list
   print 'Total kinds of Animals: %s' % Sum

我收到一条错误消息" File "sum_count.py", line 17, in <module> Sum=sum(Output) # Sum function requires a list TypeError: unsupported operand type(s) for +: 'int' and 'str'".

到目前为止我发现的是,因为sum显然要求输入类型是一个列表,我将计数数据(它是字符串)转换为一个列表,但是当我这样做时Output=list('%s' % count),似乎所有计数数据都超过 2数字是分开的。例如,当我打印输出时,它会是这样的:

['1', '6', '3']
['3']
['1', '8', '5', '9']
['7', '9']

代替

['163']
['3']
['1859']
['79']

我在这里要做的是获得这些元素的单一“总和”。在这里,它将是 4。四种动物。

我在想这可能是我收到上述错误的原因。我可能错了,但有人可以帮我解决这个问题吗?提前谢谢你的帮助!

4

4 回答 4

3

我认为你不需要使用sum.

试试这个:

for (Name, count) in sorted(counts.iteritems()):
    print 'Species total: %s' % count

或者,可能更好:

for (Name, count) in sorted(counts.iteritems()):
    print 'Total for species %s: %s' % (Name, count)

sum适用于当您有一个数字列表并想要找到该数字列表的总和时。你已经收集了每只动物的总和counts——你只需要显示它。

编辑

要总结计算的动物总数,您可以这样做:

total = sum(counts.values())
print 'Total number of animals: %d' % total

编辑 2

计算的动物种类数就是counts字典的长度:

print 'Number of kinds of animals: %d' % len(counts)
于 2012-08-03T17:29:15.707 回答
2

(在评论讨论后重新编写;原始答案只是指出 OP 正在尝试添加字符串。)

其他答案有更多的扩展机会(所以我会推荐它们),但如果您只想快速计算动物类型的数量,您可以简单地计算文件中的行数并使用您对文件是结构化的。例如,如果你的 csv 文件有一个像Name, Count, etc.下一行一样的标题,后面只有你感兴趣的数据,那么动物的数量将是文件中非空行的数量,减去一个作为标题。然后,您可以使用以下代码打印计数:

print sum(1 for line in open('test.csv') if line.strip() != '') - 1

以下是该代码的每个部分的作用:

  • sum()在其中添加列表的所有元素。在这种情况下,里面没有一个列表,而是一个生成器表达式,这里可以认为是一个没有进入内存的列表。
  • 1 for line in open('test.csv')这是生成器表达式的第一部分。它本身会产生一个生成器,其长度是其中的行数,test.csv并且每个元素都在其中(如果文件中有五行1,类似的列表将是)。[1,1,1,1,1]
  • if line.strip() != ''这是生成器表达式的第二部分。它确保 a1仅在行上有任何内容时才添加到生成器中。
  • -1从返回值中减去一个sum(...)以忽略 csv 的标头

好吧,我希望在某种程度上有所帮助,我应该重申,这种方法只是一种快速而肮脏的方法;例如,如果您正在对数据做其他事情,您就不会使用它。

于 2012-08-03T17:24:54.600 回答
2

获取计数

我认为问题源于您将“计数”与“总数”区分开来。“计数”该项目的出现总数。此外,您正在滥用collections.Counter(),它可以使您的工作变得轻松。这是我认为您要实现的目标的编码示例:

counts = collections.Counter(line[1] for line in reader if len(line) > 1)
#Now all the occurrences of each item are summed up, AND ordered by number of occurrences

print "Total number of animals: %d" % len(counts)
#This is what I THINK you are trying to do. 

此外:

for name, number in counts.items():
    print "# of %s: %d" % (name, number)

关于你的`TypeError`:

您有一个字符串列表,而不是整数列表。

一个例子:

mylist = ['1', '2', '3']

所做sum()的只是对可迭代对象执行累积加法,类似于:

total = 0
for item in mylist:
    total = total + item

在这种情况下total是一个int(值 0)并且item是一个str(值 '1')。Python 不知道如何处理0 + 'string'.

于 2012-08-03T17:28:52.957 回答
0

首先,您使用的是 Counter 对象,但仅将其用作 defaultdict 的替代品。如果你想用它来做你的计数,你可以像这样传递你的输入(假设物种出现不止一次,你想知道每个物种出现的频率):

counts = collections.Counter(map(lambda item: item[0], reader))

但是如果你想计算所有动物的总和(不管物种),你必须在你的第一个循环中添加这个计数。正如其他人所说,由于您正在读取字符串,因此您首先必须从该计数中取出一个整数。

import csv

reader=csv.reader(open('in','rb'), delimiter='\t')

counts = dict()

for data in reader:
    animal = data[1]
    if animal not in counts:
        counts[animal]= 1
    else:
        counts[animal]+= 1

for animal in counts:
    print 'Animals of scpecies %s: %s' % (animal, counts[animal])   

print 'Species total: %s' % len(counts)
print 'All animals: %s' % sum(counts.values())
于 2012-08-03T17:52:34.373 回答