繁体   English   中英

用python解析tsv文件

[英]parsing tsv file with python

我有一个很大的 tsv 文件,里面有很多我需要用 python 解析的列。 我需要获取原始文件,删除不必要的列或数据,并使用数据创建一个新文件。 一个问题,其中一列包含用逗号分隔的数据。

文件数据如下所示:

Mark    Adams    8429    Main    TX    beef,broccoli,carrot,chicken
John    Baker    1241    Wells    TX    tortilla,grapes,corn,steak
Joe    Hills    1235    Wilcox    TX    mushrooms,bacon,chicken,butter,yogurt,eggs
White    Fang    9999    Wolf    TX    salt,pepper,lettuce,lamb
Zach    Trott    0421    Spirit    TX    peas,milk,pork,cups,chicken

例子.tsv

example_output.tsv

我需要新文件包含第 0、1、2、3、4 列,并且只从第 5 列中获取特定值,这些值存储在下面的列表中。 我需要它只返回列出的任何肉,而忽略第 5 列中的其余项目。

list = ['beef', 'pork', 'chicken', 'steak', 'bacon', 'lamb'] 

这甚至可能吗? 我正在使用的当前代码...

keys = [True, True, True, True, True, []]
# Columns matching True are included, False excludes them.
# A nested list causes the tab-separated column to be split at commas and filtered equally.

from itertools import compress

with open("test.txt") as in_file, open("file2.tsv") as out_file:
for line in in_file:
    output = []
    columns = line.split("\t")
    for c, k in zip(columns, keys):
         if isinstance(k, list):
             output.append(",".join(compress(c.split(","), k)))
         elif k:
             output.append(c)
    print(*output, sep="\t", file=out_file)

到目前为止的错误: 1.) 它只选择了与我写的 True 语句一样多的第 5 列中的项目。 但是每一行都有不同数量的项目。 所以我需要它遍历每行第 5 列中的每个逗号分隔值,并返回列表中的值。

2.) 当我尝试运行最后一条打印语句时,我也遇到了语法错误。

谢谢!

由于您尚未提供任何代码示例来表明您是否已尝试解决此问题,因此我将坚持提供一种您可以尝试的可能的(非常基本的)算法:

  1. 从 TSV 中读取一行
  2. 使用“TAB”作为分隔符拆分 --> 这会给你一个列表
  3. 将上一步中获得的列表中所需的列(元素)写入输出文件(在新行中)
  4. 对于最后一列,您可以使用逗号作为分隔符进行拆分,然后根据需要处理结果列表(提示:也许del关键字可能对您有用)
  5. 冲洗并重复:返回步骤 1,直到处理完整个文件

您可以创建一个键来定义要保留哪些列和子字段以及哪些要丢弃和处理您的文件:

keys = [True, True, True, True, False, [True, False, False, True]]
# Columns matching True are included, False excludes them. 
# A nested list causes the tab-separated column to be split at commas and filtered equally.

from itertools import compress

with open("file.tsv") as in_file, open("file2.tsv", "w") as out_file:
    for line in in_file:
        output = []
        columns = line.split("\t")
        for c, k in zip(columns, keys):
             if isinstance(k, list):
                 output.append(",".join(compress(c.split(","), k)))
             elif k:
                 output.append(c)
        print(*output, sep="\t", file=out_file)

使用它作为输入文件(制表符分隔的列):

first_name1 last_name1  house_number1   street1 state1  meat1,carrots1,soup1,3 eggs1
first_name2 last_name2  house_number2   street2 state2  meat2,carrots2,soup2,3 eggs2
first_name3 last_name3  house_number3   street3 state3  meat3,carrots3,soup3,3 eggs3
first_name4 last_name4  house_number4   street4 state4  meat4,carrots4,soup4,3 eggs4

将在第二个文件中产生此输出:

first_name1 last_name1  house_number1   street1 meat1,3 eggs1
first_name2 last_name2  house_number2   street2 meat2,3 eggs2
first_name3 last_name3  house_number3   street3 meat3,3 eggs3
first_name4 last_name4  house_number4   street4 meat4,3 eggs4

查看 ideone.com 上运行的此代码


更新:

当您阐明最后一列的拆分方式时,这里有一个更新的代码示例,可让您设置单词列表,以便只在输出中显示列出的单词:

keys = [True, True, True, True, False, ['beef', 'pork', 'chicken', 'steak', 'bacon', 'lamb']]

for line in in_file:
    output = []
    columns = line.split("\t")
    for c, k in zip(columns, keys):
        if isinstance(k, list):
            output.append(",".join(word for word in c.split(",") if word in k))
        elif k:
            output.append(c)
    print(*output, sep="\t", file=out_file)

您的示例输入:

Mark    Adams     8429    Main      TX    beef,broccoli,carrot,chicken
John    Baker     1241    Wells     TX    tortilla,grapes,corn,steak
Joe     Hills     1235    Wilcox    TX    mushrooms,bacon,chicken,butter,yogurt,eggs
White    Fang     9999    Wolf      TX    salt,pepper,lettuce,lamb
Zach     Trott    0421    Spirit    TX    peas,milk,pork,cups,chicken

您的示例的输出:

马克亚当斯 8429 主牛肉、鸡肉 约翰贝克 1241 威尔斯牛排 乔希尔斯 1235 威尔科克斯培根、鸡肉 白牙 9999 狼羊肉 Zach Trott 0421 精神猪肉、鸡肉

查看 ideone.com 上运行的此代码


Python 2 的重要说明:

上面的两个脚本是为 Python 3 编写的。如果您使用的是 Python 2,则print()函数在那里不可用。 在这种情况下,您必须使用不同的方法来编写输出文件。

只需替换此行:

        print(*output, sep="\t", file=out_file)

有了这个:

        out_file.write("\t".join(output) + "\n")

其余的应该是兼容的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM