如果像元值是另一个像元值的子字符串,则使用Pandas标记两者

kpbwa7wx  于 2023-03-11  发布在  其他
关注(0)|答案(2)|浏览(114)

一个包含人名的完整和简短形式的列,我想统一它们,如果名字是另一个名字的一部分。例如,“James.J”和“James.Jones”,我想将它们都标记为“James.J”。

data = {'Name': ["Amelia.Smith",
"Lucas.M",
"James.J",
"Elijah.Brown",
"Amelia.S",
"James.Jones",
"Benjamin.Johnson"]}

df = pd.DataFrame(data)

我不知道如何在Pandas中做到这一点。所以只有一个xlrd的方式,与相似率的SequenceMatcher(并排序它手动在Excel中):

import xlrd
from xlrd import open_workbook,cellname
import xlwt
from xlutils.copy import copy 

workbook = xlrd.open_workbook("C:\\TEM\\input.xlsx")

old_sheet = workbook.sheet_by_name("Sheet1")

from difflib import SequenceMatcher

wb = copy(workbook) 
sheet = wb.get_sheet(0) 

for row_index in range(0, old_sheet.nrows):

    current = old_sheet.cell(row_index, 0).value
    previous = old_sheet.cell(row_index-1, 0).value
    sro = SequenceMatcher(None, current.lower(), previous.lower(), autojunk=True).ratio()

    if sro > 0.7:
        sheet.write(row_index, 1, previous)
        sheet.write(row_index-1, 1, previous)

wb.save("C:\\TEM\\output.xls")

Pandas的好方法是什么?

lg40wkob

lg40wkob1#

使用Pandas,利用str.split.map以及一些布尔条件来识别复制品。

df1 = df['Name'].str.split('.',expand=True).rename(columns={0 : 'FName',  1 :'LName'})

df2 = df1.loc[df1['FName'].duplicated(keep=False)]\
     .assign(ky=df['Name'].str.len())\
     .sort_values('ky')\
     .drop_duplicates(subset=['FName'],keep='first').drop('ky',1)
df['NewName'] = df1['FName'].map(df2.assign(newName=df2.agg('.'.join,1))\
                             .set_index('FName')['newName'])


print(df)

               Name   NewName
0      Amelia.Smith  Amelia.S
1           Lucas.M       NaN
2           James.J   James.J
3      Elijah.Brown       NaN
4          Amelia.S  Amelia.S
5       James.Jones   James.J
6  Benjamin.Johnson       NaN
nhhxz33t

nhhxz33t2#

这是一个使用apply和自定义函数的例子,对于小的dfs来说应该没问题;这对于大的dfs不是很好的扩展。2一个更复杂的memo数据结构是一个不错的地方,可以在不降低可读性的前提下提高性能:

df = df.sort_values("Name")
def short_name(row, col="Name", memo=[]):
    name = row[col]
    for m_name in memo:
        if name.startswith(m_name):
            return m_name
    memo.append(name)
    return name

df["short_name"] = df.apply(short_name, axis=1)        
df = df.sort_index()

输出:

Name        short_name
0      Amelia.Smith          Amelia.S
1           Lucas.M           Lucas.M
2           James.J           James.J
3      Elijah.Brown      Elijah.Brown
4          Amelia.S          Amelia.S
5       James.Jones           James.J
6  Benjamin.Johnson  Benjamin.Johnson

相关问题