【问题标题】:Suppress one csv file against another where values contain specific strings将一个 csv 文件抑制到另一个值包含特定字符串的文件
【发布时间】:2018-11-19 14:21:02
【问题描述】:

我正在尝试使用 python 删除 file1.csv 中包含 file2.csv 中的字符串的所有行。我希望它搜索 file1.csv 的 column1 中的所有值,并删除 column1 在其值中包含与 file2.csv 中相同的字符串的整行。

我知道 bash 中的 grep -v 只需一个命令即可完成相同的操作。但是,我需要针对 file2.csv 中的 40,000 多个可能的字符串 抑制 file1.csv。执行此命令时,Bash 需要很长时间,甚至崩溃。

有没有人知道一个可靠的脚本,它可以做 grep -v 在 python 中所做的事情,但在抑制包含数千个字符串的文件时?

只是为了确保清楚:

文件1.csv:

column1,column2,column3
www.gamai4xheifw.com,4410,22
www.vfekjfwo11k.com,772,100
www.gosi4xnbdn.com,1793,39
www.tum33kkwfl.com,1100,2
www.eei4xelwf.com,9982,14

文件2.csv:

column1
i4x

文件3.csv:

column1,column2,column3
www.vfekjfwo11k.com,772,100
www.tum33kkwfl.com,1100,2

但是,再次,我在 python 中需要它,因为 file2.csv 中的字符串数超过 40,000。

【问题讨论】:

  • 所以我知道 file1 中的每一行都将与 file2 中的 40000 个字符串进行比较?

标签: python csv suppression


【解决方案1】:

可能适用于您的用例的一种解决方案是第三方库 Pandas + regex。

但是,我强烈建议您使用更高效的算法,例如实现基于 trie 的Aho-Corasick 的算法,例如this solution

import pandas as pd
from io import StringIO

mystr1 = StringIO("""column1,column2,column3
www.gamai4xheifw.com,4410,22
www.vfekjfwo11k.com,772,100
www.gosi4xnbdn.com,1793,39
www.tum33kkwfl.com,1100,2
www.eei4xelwf.com,9982,14""")

mystr2 = StringIO("""column1
i4x""")

# read files, replace mystr1 / mystr2 with 'File1.csv' / 'File2.csv'
df = pd.read_csv(mystr1)
df_filter = pd.read_csv(mystr2)

# create regex string from filter values
str_filter = '|'.join(df_filter['column1'])

# apply filtering
df = df[~df['column1'].str.contains(str_filter)]

# export back to csv
df.to_csv('file_out.csv', index=False)

print(df)

               column1  column2  column3
1  www.vfekjfwo11k.com      772      100
3   www.tum33kkwfl.com     1100        2

【讨论】:

  • 嗨@jpp,感谢您的帮助!我想知道如果 file1.csv 和 file2.csv 中的行数都是几十万,我该如何定义 mystr1 和 mystr2?有没有更短的方法可以放入脚本? File2.csv 有 500k 行,file2.csv 有 45k 行。当我在 python 中执行脚本时,它们都不适合脚本。还是我错过了什么?
  • 用您的文件名替换它们,即'File1.csv''File2.csv'。我将您的数据包含在我的问题中以显示可重复的结果。
  • 好的,但是在运行 df = df[~df['column1'].str.contains 后,我不断收到此错误,“TypeError:'Series' 对象是可变的,因此它们不能被散列” (str_filter)
  • @BillythePoet,您的 csv 文件似乎与您的问题中显示的格式不完全相同。从我的脚本中可以看出,使用提供的数据,它可以工作。
  • 所以我在不同的数据集上进行了尝试。它似乎与那些> 10mb的大小一起工作。以上任何内容,我都会得到不正确的输出,其中一些应该在文件中被抑制的行。但这肯定比我在其他地方找到的要好:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-10
  • 1970-01-01
  • 1970-01-01
  • 2012-05-01
相关资源
最近更新 更多