我有两个以下格式的CSV文件:
==
FirstName | LastName | Email
Steven | Smith | stevesmith1@gmail.com
Jane | Brown | jb155@yahoo.com
Paul | Gibson | paulgibbs@outlook.com
==
ID | FirstName | LastName | IncompleteEmail
1028332982 | Steven | Smith | s*****1@g*l.com
1028820233 | Jane | Brown | j******n@yahoo.com
934943823 | Paul | Gibson | p*****s@h****l.com
==
我想以此为基础在两个CSV文件之间进行匹配-如果FirstName
和LastName
相同,则第一个CSV文件中的Email
与{ {1}}在第二个CSV中,应创建包含IncompleteEmail
在上面的示例中,输出将如下所示:
ID | Email
其原因是因为两个CSV中的“ Steve”和“ Smith”相同,并且ID | Email
1028332982 | stevesmith1@gmail.com
模式与电子邮件匹配。其他输入不匹配,因为IncompleteEmail
模式与电子邮件不匹配。
我以前曾经使用IncompleteEmail
脚本(例如join
)来处理类似文件,但是我不知道如何修改联接脚本以使用模式而不是完全匹配。我知道AWK可能会采用类似的方法,但我愿意提出建议。
需要一些可以处理大量输入的东西(两个CSV,每个CSV超过1000万行)。
谢谢。
答案 0 :(得分:1)
假设您要对*
的任何重复进行相同的处理,就像在正则表达式中对.*
进行处理,而对其他所有RE元字符(例如.
)进行按字面处理一样, ^
不能出现在电子邮件地址中:
$ cat tst.awk
BEGIN { FS=" [|] "; OFS=" | " }
FNR==1 {
for (i=1; i<=NF; i++) {
f[$i] = i
}
}
{ name = $(f["FirstName"]) FS $(f["LastName"]) }
NR==FNR {
name2fullEmail[name] = $(f["Email"])
next
}
FNR==1 {
print "ID", "Email"
next
}
name in name2fullEmail {
fullEmail = name2fullEmail[name]
partEmail = $(f["IncompleteEmail"])
gsub(/./,"[&]",partEmail)
gsub(/[[][*][]]/,".*",partEmail)
if (fullEmail ~ "^"partEmail"$") {
print $(f["ID"]), fullEmail
}
}
$ awk -f tst.awk file1 file2
ID | Email
1028332982 | stevesmith1@gmail.com
答案 1 :(得分:0)
我认为您的第一个csv
文件是df1
,第二个csv
是df2
。因此,您可以尝试以下方法:
import pandas as pd
import re
df_new = pd.merge(df1,df2, on=['FirstName','LastName'], how='inner')
mails = []
regex = "((\w{1})\D.*(\w{1}\@\w{1})\D.*(\w{1}[\.]\D.+)"
for d in range(len(df_new)):
inmail = re.findall(regex,df_new.iloc[d]["IncompleteEmail"])
commail = re.findall(regex,df_new.iloc[d]["Email"])
if inmail == commail:
mails.append([df_new.iloc[d]['ID'],df_new.iloc[d]["Email"]])
pd.DataFrame(mails, columns=["ID","Email"])
输出:
ID Email
0 1028332982 stevesmith1@gmail.com
答案 2 :(得分:0)
另一个awk:
$ awk -F" [|] " -v OFS="|" ' # set field separators
NR==FNR { # process first file
a[$1 OFS $2]=$3 # hash email, use name as key
next
}
((i=$2 OFS $3) in a) { # process second file
gsub(/\./,"\\.",$4) # escaping: . -> \.
gsub(/\*+/,".*",$4) # *{1,n} -> .*
if(FNR==1 || a[i]~$4) # if header record or regex match
print $1,a[i] # then output
}' file1 file2 # mind the order
输出:
ID|Email
1028332982|stevesmith1@gmail.com
在处理第二个文件file2
gsub(/\*+/,".*",$4)
时,尝试使电子邮件正则表达式为 ish :s*****1@g*l.com
-> s.*1@g.*l\.com
。提供的样本数据除*
和.
之外没有其他正则表达式元字符,但其他数据(例如+
)也应转义以避免误匹配,但我不确定是否对他们有特殊的意义,就像您对*
一样。
此外,它不会容忍file1
中重复的名称。最后的胜利。