使用Python在一列中选择具有值的特定范围的行(Use Python to select rows

2019-06-24 01:13发布

我知道这是简单的,但我是一个新用户到Python,所以我在这里有一个有点麻烦。 我使用Python 3的方式。

我有一个看起来像这样多个文件:

作者日期年龄,性别COLOR

Name Date Age Sex Color
Ray  May  25.1 M  Gray
Alex Apr  22.3 F  Green
Ann  Jun  15.7 F  Blue

(假装这是制表符分隔的。我要补充的是,真正的文件将拥有约3000行和17-18列)

我想要做的是选择所有这些都在年龄列小于23的值的行。

在这个例子中,输出将是:

Name Date Age Sex Color
Alex Apr  22.3 F  Green
Ann  Jun  15.7 F  Blue

这里就是我试图做的:

f = open("addressbook1.txt",'r')
line = f.readlines()
file_data =[line.split("\t")]
f.close()

for name, date, age, sex, color in file_data:
    if age in line_data < 23:
        g = open("college_age.txt",'a')
        g.write(line)
    else:
        h = open("adult_age.txt",'a')
        h.write(line)

现在,理想情况下,我的这些“地址簿” inputfiles 20-30,我想这个脚本来遍历所有这些,与23岁以下添加的所有条目相同的输出文件(“college_age.txt”)。 我真的不需要保持对其他行,但我不知道还有什么与他们无关。

这个脚本,当我运行它,产生一个错误。

AttributeError: 'list' object has no attribute 'split'

然后,我改变第三行:

file_data=[line.split("\t") for line in f.readlines()]

它不再给我一个错误,而是简单地做什么都没有。 这只是开始,然后开始。

任何帮助吗? :)还记得我是哑巴与Python。

我应该补充说,我的实际数据有小数和不是整数。 我已经编辑上面的数据,以反映。

Answer 1:

这里的问题是,你正在使用readlines()的两倍,这意味着数据被读取的第一次,然后什么都不留下的第二次。

您可以在文件中直接迭代,而无需使用readlines() -事实上,这是更好的办法,因为它不会在一次读取整个文件。

虽然你可以做你正在尝试使用做str.split()如你有更好的选择是使用的csv模块 ,它是专为任务。

import csv

with open("addressbook1.txt") as input, open("college_age.txt", "w") as college, open("adult_age.txt", "w") as adult:
   reader = csv.DictReader(input, dialect="excel-tab")
   fieldnames = reader.fieldnames
   writer_college = csv.DictWriter(college, fieldnames, dialect="excel-tab")
   writer_adult = csv.DictWriter(adult, fieldnames, dialect="excel-tab")
   writer_college.writeheader()
   writer_adult.writeheader()
   for row in reader:
       if int(row["Age"]) < 23:
          writer_college.writerow(row)
       else:
          writer_adult.writerow(row)

那么,我们在这里做什么? 首先,我们使用了with语句用于打开文件 。 这不仅更Python和可读性,但关闭句柄给你,发生异常时也是如此。

接下来,我们创建一个DictReader从文件中读取字典行,自动使用第一行作为字段名。 然后,我们让作家写回我们的分割文件,并在写标题。使用DictReader是偏好的问题。 它通常用于更在您访问数据很多(当你不知道列的顺序),但它使代码漂亮可读这里。 你可以,但是,只需使用标准csv.reader()

通过该文件中的行接下来我们循环,检查年龄(我们转换为int,所以我们可以做一个数值比较)知道写的是什么文件。 在with语句关闭了文件,对我们来说。

对于多个输入文件:

import csv

fieldnames = ["Name", "Date", "Age", "Sex", "Color"]
filenames = ["addressbook1.txt", "addressbook2.txt", ...]

with open("college_age.txt", "w") as college, open("adult_age.txt", "w") as adult:
   writer_college = csv.DictWriter(college, fieldnames, dialect="excel-tab")
   writer_adult = csv.DictWriter(adult, fieldnames, dialect="excel-tab")
   writer_college.writeheader()
   writer_adult.writeheader()
   for filename in filenames:
       with open(filename, "r") as input:
           reader = csv.DictReader(input, dialect="excel-tab")
           for row in reader:
               if int(row["Age"]) < 23:
                  writer_college.writerow(row)
               else:
                  writer_adult.writerow(row)

我们只是在添加一个循环来工作在多个文件。 请注意,我还添加字段名的列表。 以前我只是用领域和顺序的文件,但是我们有多个文件,我想这将是更明智的做在这里。 另一种方法是使用的第一个文件,以获得字段名。



Answer 2:

我觉得这是更好地使用CSV模块,以读取这些文件http://docs.python.org/library/csv.html



Answer 3:

ITYM

with open("addressbook1.txt", 'r') as f:
    # with automatically closes
    file_data = ((line, line.split("\t")) for line in f)
    with open("college_age.txt", 'w') as g, open("adult_age.txt", 'w') as h:
        for line, (name, date, age, sex, color) in file_data:
            if int(age) < 23: # float() if it is not an integer...
                g.write(line)
            else:
                h.write(line)

它看起来像文件中的数据是通过多次迭代。 但由于该生成器表达式 , file data仅仅是一个发电机省高院文件的下一行,如果要求这样做。 而且它要求在for循环这样做。 这意味着,由for循环来自发生器检索每一个项目file_data以及其中在请求每个文件行获取变换成一个元组保持完整的线(复印)在其组件(用于测试)。

另一种可能是

file_data = ((line, line.split("\t")) for line in iter(f.readline, ''))
  • 它更接近于readlines()比遍历文件。 由于readline()动作场面从遍历所有文件略有不同的背后,可能有必要这么做。

(如果你不喜欢函数式编程,您也可以手动创建一个生成函数调用readline()直到返回一个空字符串。

如果你不喜欢嵌套发电机可言,你可以做

with open("addressbook1.txt", 'r') as f, open("college_age.txt", 'w') as g, open("adult_age.txt", 'w') as h:
    for line in f:
        name, date, age, sex, color = line.split("\t")
        if int(age) < 23: # float() if it is not an integer...
            g.write(line)
        else:
            h.write(line)

这不完全一样的。)



文章来源: Use Python to select rows with a particular range of values in one column