Python 2.7匹配CSV文件的行中的精确字符串
我有一个csv文件,其中包含特定列中的字符串和其他值中的其他值。我也有一个字符串列表。 在线上循环,我想检查列表中的一个字符串是否完全包含在csv文件的行中。 如果是,则该行必须写入新的csv文件。Python 2.7匹配CSV文件的行中的精确字符串
CSV文件就像是行的列表:
22/06/2017 04:00:32 | string1 | value1
22/06/2017 04:00:32 | string11 | value2
22/06/2017 04:00:32 | string2 | value3
22/06/2017 04:00:32 | string3 | value4
我写了这个代码,它工作正常,但它没有考虑串的“精确”匹配。
import os, csv
def filter_csv(folderpath):
list1 = [
('name1',1,'string1','value1'),
('name2',2,'string2','value2'),
('name3',3,'string3','value3'),
('name4',4,'string4','value4'),
...
]
def column(matrix, i):
return [row[i] for row in matrix]
col = column(list1,2)
for file in os.listdir("%s" % folderpath):
if file.endswith(".csv"):
new_file = 'new_'+file
filepath = os.path.join("%s" % folderpath, file)
new_filepath = os.path.join("%s" % folderpath, new_file)
with open('%s' % filepath) as csvfile:
lines = csvfile.readlines()
with open('%s' % new_filepath, 'wb') as csvfile2:
for line in lines:
for namevar in col:
if namevar in line:
csvfile2.write(line)
return
如何为csv文件的列添加字符串的精确匹配?
只是提出使用不同的库,现在,我想它可能是矫枉过正一个稍微不同的解决方案,但你可能会喜欢它:)你应该能够修改示例以插入到你的代码.. 。
import pandas as pd
# Dummy col
col = ["string1", "string2", "string3"]
# Read in CSV file
df = pd.read_csv("test.csv", header=None, skipinitialspace=True, delimiter ="|")
# Strip all strings so that trailing whitespace is ignored.
# csv library OP used would also be "fooled" by whitepace
df_obj = df.select_dtypes(['object'])
df[df_obj.columns] = df_obj.apply(lambda x: x.str.strip())
# Select only rows with any column that has a value in col
df = df[df.isin(col).any(axis=1)]
# Write out CSV to new file
df.to_csv("test2.csv")
这将通过检查每一列中col
的值之一过滤CSV的每一行。如果任何列的值为col
,则它会显示在输出CSV文件中。
我发现的一件事是,如果CSV中的文本有尾随空格,完全匹配将无法工作。例如,在string1
以下的CSV行中,由于尾随空格而不能完全匹配。
value1, value2, string1 , value3
因此,修剪所有字符串的额外代码。使用csv
库进行测试,它会有同样的问题。如果你知道你的CSV字符串永远不会有尾随空格,那么你甚至可以删除这两行。然后代码过滤,完全形成你的榜样,是(借用Tomalak's use of glob
):
import pandas as pd
import glob
import os
def filter_csv(folderpath):
list1 = [
('name1',1,'string1','value1'),
('name2',2,'string2','value2'),
('name3',3,'string3','value3'),
('name4',4,'string4','value4')
]
def column(matrix, i):
return [row[i] for row in matrix]
col = column(list1,2)
for filepath in glob.glob("%s/*.csv" % folderpath):
filename = os.path.basename(filepath)
new_filepath = os.path.join(folderpath, 'new_' + filename)
df = pd.read_csv(filename, header=None, skipinitialspace=True, delimiter ="|")
df_obj = df.select_dtypes(['object'])
df[df_obj.columns] = df_obj.apply(lambda x: x.str.strip())
df[df.isin(col).any(axis=1)].to_csv(new_filepath, sep="|", header=False, index=False)
但如果空白是不是一个问题,你可以修剪下的线条勾勒出代码:
df_obj = df.select_dtypes(['object'])
df[df_obj.columns] = df_obj.apply(lambda x: x.str.strip())
太棒了!这工作!只需添加参数sep =';'在行中:df = pd.read_csv(filename,sep =';',header = None,skipinitialspace = True) – giube
你想要做的是写一个过滤列表到文件。
过滤条件是“某些预定义的有效值之一必须出现在CSV行”上,我们可以为此设置一个交集。我们需要一组有效值,并且当它们与当前输入行相交并且剩余一些时,则当前输入行通过。
import os, csv
from glob import glob
def filter_csv(folderpath):
list1 = [
('name1',1,'string1','value1'),
('name2',2,'string2','value2'),
('name3',3,'string3','value3'),
('name4',4,'string4','value4'),
# ...
]
# prepare a set of valid values
valid_values = {row[2] for row in list1}
for filepath in glob("%s/*.csv" % folderpath):
filename = os.path.basename(filepath)
new_filepath = os.path.join(folderpath, 'new_' + filename)
with open(filepath, newline='') as infile, \
open(new_filepath, 'wb') as outfile:
reader = csv.reader(infile)
writer = csv.writer(outfile)
filtered_rows = (row for row in reader if valid_values.intersection(row))
writer.writerows(filtered_rows)
注
- 3210是通过扩展
-
with
可以处理多个资源 - 可以使用
\
跨越多行 - 集优化查找文件非常有用用于查找匹配值
-
{ ... }
是一套理解 - 它变成一个列表转换成一组 - 始终解析使用CSV模块CSV文件 - 从不使用
.split()
或类似的东西
“精确”匹配我的意思是:如果CSV有是“string111”它写入新的csv文件,因为“string1”包含在“string111”中,但我不希望如此,我只想在第一个csv中存在“string1”的情况下写入新的csv文件文件。 – giube
csv文件是行喜欢的列表:22/06/2017 04:00:32 | string1 | value1 – giube