[英]Match Two CSVs Based on Pattern Matching in One Column
我有以下格式的兩個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
與第二個CSV中IncompleteEmail
的模式匹配,應創建包含ID | Email
的輸出ID | Email
ID | Email
在上面的示例中,輸出如下所示:
ID | Email
1028332982 | stevesmith1@gmail.com
其原因是因為兩個CSV中的“ Steve”和“ Smith”相同,並且IncompleteEmail
模式與Email匹配。 其他輸入不匹配,因為IncompleteEmail
模式與電子郵件不匹配。
我以前使用的join
腳本(如join -i -t '|' -j 1 -o 2.2,2.3 1.txt 2.txt > out.txt
)來處理類似的文件,但我不知道怎么修改連接腳本以使用模式而不是完全匹配。 我知道AWK可能會采用類似的方法,但我願意接受建議。
需要一些可以處理大量輸入的東西(兩個CSV,每個CSV超過1000萬行)。
提前致謝。
假設您希望*
的任何重復都以與.*
正則表達式中的處理方式相同,而每個其他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
我認為您的第一個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
另一個問題:
$ 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
重復名稱。 最后的勝利。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.