gpt4 book ai didi

python - 如果特定的其他列不为空,如何删除重复项但保留行(Pandas)

转载 作者:太空狗 更新时间:2023-10-30 01:17:53 24 4
gpt4 key购买 nike

我有很多重复的记录 - 其中一些有银行账户。我想保留银行账户的记录。

基本上是这样的:

if there are two Tommy Joes:
keep the one with a bank account

我已经尝试使用下面的代码进行重复数据删除,但它让受骗者没有银行账户。

df = pd.DataFrame({'firstname':['foo Bar','Bar Bar','Foo Bar','jim','john','mary','jim'],
'lastname':['Foo Bar','Bar','Foo Bar','ryan','con','sullivan','Ryan'],
'email':['Foo bar','Bar','Foo Bar','jim@com','john@com','mary@com','Jim@com'],
'bank':[np.nan,'abc','xyz',np.nan,'tge','vbc','dfg']})


df


firstname lastname email bank
0 foo Bar Foo Bar Foo bar NaN
1 Bar Bar Bar Bar abc
2 Foo Bar Foo Bar Foo Bar xyz
3 jim ryan jim@com NaN
4 john con john@com tge
5 mary sullivan mary@com vbc
6 jim Ryan Jim@com dfg



# get the index of unique values, based on firstname, lastname, email
# convert to lower and remove white space first

uniq_indx = (df.dropna(subset=['firstname', 'lastname', 'email'])
.applymap(lambda s:s.lower() if type(s) == str else s)
.applymap(lambda x: x.replace(" ", "") if type(x)==str else x)
.drop_duplicates(subset=['firstname', 'lastname', 'email'], keep='first')).index


# save unique records
dfiban_uniq = df.loc[uniq_indx]

dfiban_uniq



firstname lastname email bank
0 foo Bar Foo Bar Foo bar NaN # should not be here
1 Bar Bar Bar Bar abc
3 jim ryan jim@com NaN # should not be here
4 john con john@com tge
5 mary sullivan mary@com vbc


# I wanted these duplicates to appear in the result:

firstname lastname email bank
2 Foo Bar Foo Bar Foo Bar xyz
6 jim Ryan Jim@com dfg

您可以看到保留了索引 0 和 3。这些拥有银行账户的客户的版本已被删除。我的预期结果是反过来。移除没有银行账户的受骗者。

我考虑过先按银行账户排序,但我有太多数据,我不确定如何“感知检查”它是否有效。

感谢任何帮助。

这里有几个类似的问题,但它们似乎都有可以排序的值,例如年龄等。这些散列的银行帐号非常困惑

编辑:

在我的真实数据集上尝试答案的一些结果。

@Erfan 的方法按子集+银行对值进行排序

去重后剩余 58594 条记录:

subset = ['firstname', 'lastname']

df[subset] = df[subset].apply(lambda x: x.str.lower())
df[subset] = df[subset].apply(lambda x: x.replace(" ", ""))
df.sort_values(subset + ['bank'], inplace=True)
df.drop_duplicates(subset, inplace=True)

print(df.shape[0])

58594

@Adam.Er8 使用按银行排序的值来回答。去重后剩余 59170 条记录:

uniq_indx = (df.sort_values(by="bank", na_position='last').dropna(subset=['firstname', 'lastname', 'email'])
.applymap(lambda s: s.lower() if type(s) == str else s)
.applymap(lambda x: x.replace(" ", "") if type(x) == str else x)
.drop_duplicates(subset=['firstname', 'lastname', 'email'], keep='first')).index

df.loc[uniq_indx].shape[0]

59170

不确定为什么会出现差异,但两者非常相似。

最佳答案

您应该按 bank 列对值进行排序,使用 na_position='last'(因此 .drop_duplicates(..., keep='first' ) 将保留一个不是 na 的值。

试试这个:

import pandas as pd
import numpy as np

df = pd.DataFrame({'firstname': ['foo Bar', 'Bar Bar', 'Foo Bar'],
'lastname': ['Foo Bar', 'Bar', 'Foo Bar'],
'email': ['Foo bar', 'Bar', 'Foo Bar'],
'bank': [np.nan, 'abc', 'xyz']})

uniq_indx = (df.sort_values(by="bank", na_position='last').dropna(subset=['firstname', 'lastname', 'email'])
.applymap(lambda s: s.lower() if type(s) == str else s)
.applymap(lambda x: x.replace(" ", "") if type(x) == str else x)
.drop_duplicates(subset=['firstname', 'lastname', 'email'], keep='first')).index

# save unique records
dfiban_uniq = df.loc[uniq_indx]

print(dfiban_uniq)

输出:

  bank    email firstname lastname
1 abc Bar Bar Bar Bar
2 xyz Foo Bar Foo Bar Foo Bar

(这只是您的原始代码,在 uniq_indx = ... 的开头带有 .sort_values(by="bank", na_position='last'))

关于python - 如果特定的其他列不为空,如何删除重复项但保留行(Pandas),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56852581/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com