【问题标题】:Python: Getting a sum of counts obtained in PythonPython:获取在 Python 中获得的计数总和
【发布时间】:2012-08-03 17:21:30
【问题描述】:

我是一个每天都在与 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 位的计数数据都被拆分。比如我打印Output的时候是这样的:

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

而不是

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

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

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

【问题讨论】:

  • 为什么你想要['163'] 形式的对象而不是163sum() 确实 要求输入类型为列表,但我认为您的列表构造错误。此外,字符串是可迭代的,当您执行list(some_string) 时,它会将字符串转换为字符列表。
  • 你是对的。我只想要一个形式为 163 的对象。在这种情况下,我希望 Python 执行 163+3+1859+79。有什么办法吗?
  • 对不起,我的意思是 4。我再次编辑了问题。很抱歉让你感到困惑......
  • @JoelCornett sum() does require the input type to be a list - 不正确 - 它要求它的参数是任何可迭代的。
  • @JonClements:我的错误。这就是我的意思,但你说得对,我不能互换使用这些术语。

标签: python count sum


【解决方案1】:

我认为你不需要使用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)

【讨论】:

  • 这会将每个名称的每个计数相加吗?在这段代码之前,我有这样的东西,因为我只是想知道计数,但现在我想把它们加起来。
  • 在这种情况下,您应该能够通过total = sum(counts.values())获得总数
  • 或者,要获取动物种类的数量,total = len(counts) -- 请参阅我的答案的编辑。
  • 非常感谢您的两次编辑!他们很清楚!!编辑 2 正是我想要的,但知道差异确实有帮助。非常感谢!! :)
【解决方案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

在这种情况下,totalint(值 0),itemstr(值 '1')。 Python 不知道如何处理0 + 'string'

【讨论】:

  • 谢谢,我刚试过这个,但显然,它仍然像上面的例子那样用多位数分割数字。你有什么避免这种情况的建议吗?
  • @owl:请参阅我对上述问题的评论。什么是“物种总数”。我问的原因是因为在我看来您已经将总数收集到您的计数器字典中,并且将字典中所有项目的总数打印一堆并没有多大意义次。
  • 我刚刚再次编辑了我的问题。但是在这里我希望 Python 做一个两步的过程。先数出每一种动物,然后总结有多少种动物。在原始数据中,它类似于 [cat, cat, dog, cat, rabbit] 但我想要的是我拥有的动物数量的总和。所以在这个例子中,我想要一个总和,3(动物种类)。
  • 是的,这就是我想要的!非常感谢您,再次对我对自己的问题感到困惑表示诚挚的歉意!
【解决方案3】:

(在评论讨论后重写;原始答案只是指出 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() != '' 这是生成器表达式的第二部分。它确保只有在行上有任何内容时才会将1 添加到生成器中。
  • -1值减一sum(...)返回忽略csv的头部

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

【讨论】:

  • 感谢您的快速回复!当我尝试“Output=int('%s' % count) 时,我得到一个错误“TypeError: 'int' object is not iterable”。我应该同时做 int 和 list 吗?
  • 这不是一个好的答案。 在哪里,确切地说,他会做那个演员吗?在他目前的架构中,他做不到。他是python的初学者。你基本上是在告诉他“重组你的代码,并确保你在某个地方转换为 int”。此外,您完全错过了真正的问题,即他试图对一个字符串列表求和,即使它们是整数,也不应该被求和。
  • @PhillipSchmidt True- 我回答得太快了。当我看到 owl 正在汇总一个字符串列表并打算编辑答案以使其适合他/她的代码时,我立即做出了回应。在我进行编辑时,其他人回答了相同的信息,所以我取消了它。另外,我误读了关于猫头鹰想要总结的内容。我应该删除我的答案吗?
  • @MatthewAdams 我会尝试编辑它以正确的方式进行操作:) 看看您是否可以提出如何正确操作的新观点。作为一个初学者,我相信他想看看有多少人会这样做。
  • 是的,学习不同的方法来做同样的事情确实对我有很大帮助!我实际上正在尝试您的所有代码(这就是我的回复没有赶上的原因)。我真的很感谢你的帮助!!这真的是一个很棒的社区! :) 非常感谢您的帮助!
【解决方案4】:

首先,您使用的是 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())

【讨论】:

  • 对不起,我回来晚了,但也感谢您的帮助!目前我收到一条错误消息“print 'All animals: %s' % sum(map(lamda item: item[1], counts.items())) SyntaxError: invalid syntax” 当我删除这一行时,我得到“ValueError : 太多值无法解包”。我以前见过这个错误,但到目前为止还没有弄清楚这意味着什么......
  • 我不确定您为什么会遇到语法错误...您使用的是什么版本的 python? ValueError 表示在某些时候没有足够的值来解包。您的文件中总是有两个值吗?
  • 我使用的是 Python 2.7。项目下面有一个 ^ 标记:。有什么线索吗?关于ValueError,当你说两个值时,在我的原始数据文件中?该文件实际上非常大,有 10 多列。这就是为什么在我上面的原始代码中,我必须指定我想计算哪一列,尽管这可能与我在这里遇到的错误无关......
  • 我进行了更改,因此现在可以进行解包。此外,我删除了我认为除了该行中的名称之外的计数,并将最后一行更改为等效的内容。但基本上现在它只是山姆答案的变体。
猜你喜欢
  • 1970-01-01
  • 2019-11-26
  • 1970-01-01
  • 2013-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-18
  • 2013-06-07
相关资源
最近更新 更多