【问题标题】:CSV - remove rows in which any column is emptyCSV - 删除任何列为空的行
【发布时间】:2013-10-06 22:12:55
【问题描述】:

我正在使用来自 Kaggle 的 Titanic 数据集。我想从 train.csv 中删除任何具有空列的行(我知道这不是处理丢失数据的最佳方法,但无论如何这个问题对我来说都很有趣)。

我想采用这种 Unix 类型的方式(使用 awk、sed 或 grep 之类的工具),因为我正在努力提高这些工具的水平,但我什至不知道从哪里开始。

数据示例:

PassengerId,Survived,Pclass,Name,Sex,Age,SibSp,Parch,Ticket,Fare,Cabin,Embarked
1,0,3,"Braund, Mr. Owen Harris",male,22,1,0,A/5 21171,7.25,,S
2,1,1,"Cumings, Mrs. John Bradley (Florence Briggs Thayer)",female,38,1,0,PC 17599,71.2833,C85,C
3,1,3,"Heikkinen, Miss. Laina",female,26,0,0,STON/O2. 3101282,7.925,,S

在第二行,小屋是空的,所以我想从文件中删除它。

请注意,第四列有时包含逗号,但该列始终包含在双引号中。

旁白:

我也想知道如何仅针对特定列执行此操作,但如果此问题的答案不能帮助我回答该问题,我可以将其作为一个单独的问题提出。

【问题讨论】:

    标签: unix csv text


    【解决方案1】:

    我会坚持使用具有 解析器的语言,因为双引号内的逗号可能会出现问题。并且更容易扩展以比较特定的列。这里是 示例。它从标题中提取字段数并比较每一行的数字以确定是否打印:

    import sys 
    import csv 
    
    with open(sys.argv[1], 'r', newline='') as csvfile:
        csvreader = csv.reader(csvfile)
        csvwriter = csv.writer(sys.stdout)
        row = next(csvreader)
        fields = len(row)
        csvwriter.writerow(row)
        for row in csvreader:
            l = len(list(filter(str.strip, row)))
            if l < fields: continue
            csvwriter.writerow(row)
    

    假设代码在一个名为 script.py 的文件中,运行如下:

    python script.py infile
    

    产生:

    PassengerId,Survived,Pclass,Name,Sex,Age,SibSp,Parch,Ticket,Fare,Cabin,Embarked
    2,1,1,"Cumings, Mrs. John Bradley (Florence Briggs Thayer)",female,38,1,0,PC 17599,71.2833,C85,C
    

    【讨论】:

    • 我收到错误“TypeError: 'newline' is an invalid keyword argument for this function”。我想这可能是因为我有 python 2.7,根据pythonconquerstheuniverse.wordpress.com/2011/05/08/… 这是 python 3 的功能。
    • 如果我删除第三个参数,它会起作用。通过在 Excel 中过滤数据来直观地检查结果,看起来它可以工作。感谢您建议使用带有 csv 解析器的语言是一种可行的方法。我会接受这个。
    【解决方案2】:

    如何排除包含,, 或以, 结尾或以, 开头的行

    cat data.txt | sed -e '/,,/d' -e '/^,/d' -e '/,$/d'
    

    它并不完美,因为引用的文本可能包含,,,这并不意味着一个空列。但也许这已经足够好了?由你来评判!

    【讨论】:

      【解决方案3】:

      这是使用sed的尝试

      sed -r '/(^|,)\s*(,|$)/d' file
      

      这将删除所有包含,,、以, 结尾和以, 开头的行

      \s* 还允许删除包含仅用空格填充的任何单元格的行。

      针对特定列

      你可以试试awk

      awk -F',' '$n{print $0}' file
      

      $n 中,将n 替换为所需的列号。

      【讨论】:

      • 如果字符串,, 存在于用双引号括起来的字段中,则sed 命令失败。不太可能,但可能。 awk 的类似问题。
      猜你喜欢
      • 1970-01-01
      • 2018-08-14
      • 1970-01-01
      • 2014-04-17
      • 1970-01-01
      • 2011-05-30
      • 2015-11-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多