2

我是一名 Python 初学者,试图计算大数据集中某些大小的数量。原始数据位于由制表符分隔的文本文件中。我有不同动物的“名称”(字符串,但每一行看起来像一个列表)和不同行中的“大小”(整数)。我想计算在一定大小范围内的所有动物的数量,在 10-30 之间。

到目前为止,我已经成功计算了我拥有的每个“名称”中有多少个,但没有指定“大小”。我的代码在下面,我得到了任何错误,但它只是被忽略了。有人可以帮我为什么忽略这些代码吗?提前谢谢你的帮助!

import csv, collections

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

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

for (Name, count) in counts.iteritems():
   if 10<=Size<=30:
      print '%s: %s' % (Name, count)
4

3 回答 3

3

如所写,Size将永久设置为文件中的最后一个大小值,它不会与Name.

通过 for 循环的每一轮Size都设置为line[10],但它不存储在循环范围之外的任何内容中。Name间接存储在计数器中。所以下一次循环运行时,值会Size更改为下一个动物的大小。

每只动物是否在数据中多次出现?

您将需要稍微复杂一点的数据结构,或者在循环文件时查看大小。

如果您不介意忽略尺寸范围之外的动物:

for line in reader:
    size = float(line[10])
    if 10 <= size <= 30:
        name = line[1]
        counts[name] += 1

for name, count in counts.iteritems():
    print '%s: %s' % name, count

(注意:我已更改原始代码的大小写和空格以匹配 Python 推荐的样式指南 pep8。)

于 2012-08-01T20:36:46.537 回答
2
Size=line[10]

Size一个字符串。

10<=Size<=30

ints与字符串 ( Size)进行比较。

In [3]: 10 <= '20' <= 30
Out[3]: False

要解决此使用:

try:
    Size = float(line[10])
except (ValueError, IndexError):
    continue

以上将try...except导致您的程序跳过 csv 文件中没有第 11 列或其中包含无法转换为浮点数的字符串的行。


在 Python2 中,ints 比较小于strings。

In [4]: 10 <= '1'
Out[4]: True

信不信由你,因为iin在字母表中的字符串之前... ints

在 Python3 中,引发了 TypeError。

Python 3.2.2 (default, Sep  5 2011, 22:09:30) 
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 10 <= '1'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() <= str()

哈利路亚。

于 2012-08-01T20:34:44.040 回答
1

python 的一个很酷的功能是字典中的键可以是非常高级的东西,例如...... tadaaa!......元组(或日期,或很多东西......只要它是可散列的,正如 JF Sebastian 指出的那样- 没有什么是非法的哈希,在这里-)。将它与正则表达式结合起来,你就有了一个非常漂亮的“大小分类器” :-)

sizesFromFile = [
    "Name: Cat, Size: 3.2",
    "Name: Dog, Size: 4.2",
    "Name: BigFoot, Size: 12",
    "Name: Elephant, Size: 31.4",
    "Name: Whale, Size: 85.99",
]

import re
import sys
regex = re.compile(r"^Name:\s*(?P<name>\w+),\s+Size:\s+(?P<size>[\d\.]+)")

myRanges = {
    (0, 10): list(),
    (11, 20): list(),
    (21, 30): list(),
    (31, sys.maxint): list()
}

for line in sizesFromFile:
    match = regex.match(line)
    if match is not None:
        print "Success parsing %s, %s" % (match.groupdict()["name"], match.groupdict()["size"])
        name = match.groupdict()["name"]
        size = float(match.groupdict()["size"])
        for myRange in myRanges:
            if size >= myRange[0] and size <= myRange[1]:
                myRanges[myRange].append(name)

print "This is what I got: %s" % (myRanges)

输出:

This is what I got: {(21, 30): [], (11, 20): ['BigFoot'], (0, 10): ['Cat', 'Dog'], (31, 2147483647): ['Elephant', 'Whale']}

虽然我很确定这是非常不理想的,但速度很快......但它仍然很酷,对吧?

于 2012-08-01T20:48:48.943 回答