我正在尝试对一个包含21列和大量行的数据集进行分类。我已经到了可以将数据导入csv并打印出单独列的地步。我还有两件事要做。首先,我希望能够打印出特定的数据点。例如,位于第2行第4列中的数据点。第二个任务是根据第4列和第5列对数据行进行分类。这些列是纬度和经度。我正试图获得世界某个特定地区的争吵。所以我的想法是这个
if 60 > row[4] > 45 and 165 > row[1] > 150:
ie(就像数学运算(9>x>5))
我不确定做上述程序的正确方法是什么。
我已将代码粘贴到底部。我是python编程的新手,所以可以随意指出错误。
import csv
path = r'C:Documents and Settingseag29278My Documentspython test codetest_satdata.csv'
with open(path, 'rb') as f:
reader = csv.reader(f, delimiter=',')
for row in reader:
print row [0]
#this prints out the first column
var1 = []
for row in f:
if 60 > row[4] > 45 and 165 > row[1] > 150:
var1.append(row)
print var1
更新1
好吧,所以我更新了代码,但当我运行模块时,我得到了这个输出。。
2010年2010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010[]
所以我看到程序打印出var1,但它是空的
来自文档:
比较可以任意链接,例如,
x < y <= z
是等价的对于x < y
和y <= z
,除了y
仅被评估一次(但在两者中当发现CCD_ 6为假时,情况CCD_。
所有关于"链式比较"(例如60 > foo > 45
)的答案都完全没有切中要害。你对链式比较没有问题。但是您的代码中有很多问题。
首先,CSV读取器返回的行总是将字符串作为元素。所以如果CSV看起来像
10,20,abc,40
当你使用CSV阅读器时,它在Python中变成了
['10', '20', 'abc', '40'] # list of strings
在Python 2中,将字符串与数字进行比较"有效",因为您可以这样做,而且不会引发任何异常。但这通常不是你想要的。例如:
Python 2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> 1 < '2'
True
>>> 2 < '1'
True
请注意,Python3甚至不允许您将字符串与数字进行比较:
Python 3.2.3 (default, Apr 11 2012, 07:12:16) [MSC v.1500 64 bit (AMD64)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> 1 < '2'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < str()
>>>
因此,您需要做的一件事是将CSV中的字符串转换为整数:
>>> 1 < '2' < 3 # Python 2
False
>>> 1 < int('2') < 3
True
您需要做的另一件事是确保您正在读取CSV行,而不是文件中的普通老行。在哪里
var1 = []
for row in f:
if 60 > row[4] > 45 and 165 > row[1] > 150:
var1.append(row)
您正在做的是将每行的第5个字符与60和45进行比较,将每行第2个字符串分别与165和150进行比较。你几乎可以肯定是指
var1 = []
for row in reader:
if 60 > int(row[4]) > 45 and 165 > int(row[1]) > 150:
var1.append(row)
但不幸的是,这还不是全部。在进行时,您已经"用完"了CSV中的所有行
for row in reader:
print row [0]
在该循环结束时,reader
没有更多的行可供读取。最简单的方法是重新打开文件,并为每个循环使用一个新的读取器:
with open(path, 'rb') as f:
reader = csv.reader(f, delimiter=',') # why specify the delimiter?
for row in reader:
print row[0]
#this prints out the first column
with open(path, 'rb') as f: # we open the file a second time
reader = csv.reader(f)
var1 = []
for row in f:
if 60 > int(row[4]) > 45 and 165 > int(row[1]) > 150:
var1.append(row)
对于初学者,甚至是最有经验的Python程序员来说,这就足够了。代码清晰到显而易见的程度,这通常是一件好事。如果特殊情况要求采取更大胆的措施,那么看看过去的这些问题,寻找可能的替代方案:
在Python中可以重置迭代器吗?
为多次迭代重置csv.reader的正确方法?
此行:
if 60 > row[4] > 45 and 165 > row[1] > 150:
正在比较CCD_ 9。我猜这不是你想要的。for row in f
为文件中的每一行生成一个字符串。我想在进行这些比较之前,你应该先做一些解析。或者您可能想要迭代reader
而不是f
。f
是文件本身,而不是csv读取器。
这应该效果更好:
with open(path, 'rb') as f:
reader = csv.reader(f, delimiter=',')
var1 = [] # This is a very poorly named variable, by the way.
for row in reader:
print row [0]
if 60 > row[4] > 45 and 165 > row[1] > 150:
var1.append(row)
这在Python中实际上可以很好地工作。大多数其他语言都不允许你这么做;你必须写60 > row[4] and row[4] > 45 and ...
。
通常使用<
编写它,使其看起来更像BETWEEN
操作。。。
if (45 < row[4] < 65) and (150 < row[1] < 165):
Chaining也适用于其他运算符,例如==
、is
、in
。存在一个隐含的CCD_ 20。
你可以在这里使用列表理解
var1 = [row for row in f if 45 < row[4] < 60 and 150 < row[1] < 165]
我同意@Jon的观点。使用<
比>
读起来更自然