【问题标题】:Matching columns in pandas df complex [closed]pandas df complex中的匹配列[关闭]
【发布时间】:2022-01-09 23:00:21
【问题描述】:

在确定解决以下问题的最佳方法时需要一些帮助。 以下 df 有一组按货币显示的帐户,显示其贷方和借方的利率和代码。最右边的 4 列是要与费率数据库进行比较的费率。

df = pd.DataFrame([[5551455514,'GBP','CR',3.5,'WW',-1.0,'WW',3.5,'WW',-1.0],
                    [9631475400,'USD','CE',0,'FF',0,'CE',1.25,'FF',0],
                   [8529875405,'USD','CE',1.25,'FF',0,'CE',1.25,'FF',0],
                    [9631475400,'EUR','CE',1.25,'FF',0,'CE',1.25,'FF',0],
                    [3265415409,'USD','CE',1.25,'FF',0,'CE',1.25,'FF',0],
                    [9631475405,'USD','CE',1.25,'GG',0,'CE',1.25,'FF',0]],
columns = ['Account','Currency','Credit_Code','Credit_Rate','Debit_Code','Debit_Rate','DB_Credit_Code','DB_Credit_Rate'
           ,'DB_Debit_Code','DB_Debit_Rate'])
df

输出:


Account         Cur CR_Code CR_Rate Db_Code Db_Rate DB_CR_Code  DB_CR_Rate  DB_Db_Code  DB_Db_Rate
0   5551455514  GBP CR      3.50    WW     -1.0     WW          3.50        WW          -1.0
1   9631475400  USD CE      0.00    FF      0.0     CE          1.25        FF           0.0
2   8529875405  USD CE      1.25    FF      0.0     CE          1.25        FF           0.0
3   9631475400  EUR CE      1.25    FF      0.0     CE          1.25        FF           0.0
4   3265415409  USD CE      1.25    FF      0.0     CE          1.25        FF           0.0
5   9631475405  USD CE      1.25    GG      0.0     CE          1.25        FF           0.0

实现了以下 2 个函数,以将 CR/Db 两侧的速率/代码与速率数据库匹配。

def matching_func_credit(row):
    if row['CR_Code'] == row['DB_CR_Code'] and row['CR_Rate'] == row['DB_CR_Rate']:
        return 'Match'
    else:
        return 'NoMatch'
df['CR_Match'] = df.apply(lambda x: matching_func_credit(x),axis=1)

def matching_func_debit(row):
    if row['Db_Code'] == row['DB_Db_Code'] and row['Db_Rate'] == row['DB_Db_Rate']:
        return 'Match'
    else:
        return 'NoMatch'
df['Db_Match'] = df.apply(lambda x: matching_func_debit(x),axis=1)

执行这两个功能的结果:

Account         Cur CR_Code CR_Rate Db_Code Db_Rate DB_CR_Code  DB_CR_Rate  DB_Db_Code  DB_Db_Rate CR_Match Db_Match
0   5551455514  GBP CR      3.50    WW     -1.0     WW          3.50        WW          -1.0 NoMatch Match
1   9631475400  USD CE      0.00    FF      0.0     CE          1.25        FF           0.0 NoMatch Match
2   8529875405  USD CE      1.25    FF      0.0     CE          1.25        FF           0.0 Match Match
3   9631475400  EUR CE      1.25    FF      0.0     CE          1.25        FF           0.0 Match Match
4   3265415409  USD CE      1.25    FF      0.0     CE          1.25        FF           0.0 Match Match 
5   9631475405  USD CE      1.25    GG      0.0     CE          1.25        FF           0.0 Match NoMatch

问题: 如果一个美元账户只有以“5400”结尾,它可以有一个储备或备用账户(但不是在所有情况下),其中“5400”账户的前6位数字相同,但后4位将是“5405” ”。

如果检测到储备账户,则 5400 的贷方利率/代码匹配将仅发生在 5405 储备账户上,而不发生在 5400 上。借方利率/代码匹配将仅发生在 5400 账户上,而不发生在 5405 账户上如果检测到一个。

需要做的总结:

  1. 我的第一个挑战是如何搜索以 5400 结尾的美元账户是否有相应的 5405 账户,它们将共享相同的前 6 位数字。创建某种标志,可能是一个新列以在具有备份帐户的 5400 行上返回布尔值 Y
  2. 如何仅匹配 5400 帐户上的借方利率/代码而忽略贷方。以某种方式在信用方面进行覆盖,默认为“IgnoreHasCorAcc”
  3. 如何仅匹配 5404 帐户上的信用率/代码并忽略其借方率/代码但同时返回“IgnoreHasCorAcc”

理想情况下,我想增强上面的 2 个功能来尝试解决这个问题。

期望的结果:

ccount  Cur CR_Code CR_Rate Db_Code Db_Rate DB_CR_Code  DB_CR_Rate  DB_Db_Code  DB_Db_Rate  CR_Match    Db_Match    HasCorresAc
0   5551455514  GBP CR  3.50    WW  -1.0    WW  3.50    WW  -1.0    NoMatchOnCredit MatchOnDebit    N
1   9631475400  USD CE  0.00    FF  0.0 CE  1.25    FF  0.0 IgnoreHasCorAcc MatchOnDebit    Y
2   8529875405  USD CE  1.25    FF  0.0 CE  1.25    FF  0.0 MatchOnCredit   MatchOnDebit    N
3   9631475400  EUR CE  1.25    FF  0.0 CE  1.25    FF  0.0 MatchOnCredit   MatchOnDebit    N
4   3265415409  USD CE  1.25    FF  0.0 CE  1.25    FF  0.0 MatchOnCredit   MatchOnDebit    N
5   9631475405  USD CE  1.25    GG  0.0 CE  1.25    FF  0.0 MatchOnCredit   IgnoreHasCorAcc N

【问题讨论】:

    标签: python pandas dataframe numpy


    【解决方案1】:

    首先,如果我们将Account 列转换为字符串会更好,因为它是一个 int 并没有真正帮助我们。

    df['Account'] = df['Account'].apply(str)
    

    然后我们得到可能的个保留列表并相应地标记它们。

    df['Is_Reserve'] = df['Account'].str.endswith('5405')
    reserves = df[df['Is_Reserve']]['Account'].tolist()
    accounts = df['Account'].tolist()
    
    

    我们定义了一个自定义函数来检查给定帐户是否满足以下条件:

    • 以美元为单位
    • 它的储备出现在列表中
    • 以 5400 结尾
    def has_reserve(row):
        account = row['Account']
        if account.endswith('5405'):
            return False
        reserve = account[:6] + '5405'
        if reserve in reserves and row['Currency'] == 'USD' and account.endswith('5400'):
            return True
        else:
            return False
    
    df['Has_Reserve'] = df.apply(lambda x: has_reserve(x),axis=1)
    

    扩展第 2 点和第 3 点建议的功能:

    def matching_func_credit(row):
        if row['Has_Reserve']:
            return 'IgnoreHasCorAcc'
        else:
            if row['Credit_Code'] == row['DB_Credit_Code'] and row['Credit_Rate'] == row['DB_Credit_Rate']:
                return 'MatchOnCredit'
            else:
                return 'NoMatchCredit'
    
    df['CR_Match'] = df.apply(lambda x: matching_func_credit(x), axis=1)
    
    def matching_func_debit(row):
        account = row['Account']
        corr_account = account[:6] + '5400'
        if row['Is_Reserve'] and corr_account in accounts:
            return 'IgnoreIsRes'
        if row['Debit_Code'] == row['DB_Debit_Code'] and row['Debit_Rate'] == row['DB_Debit_Rate']:
            return 'MatchOnDebit'
        else:
            return 'NoMatchInDebit'
        
    df['Db_Match'] = df.apply(lambda x: matching_func_debit(x), axis=1)
    

    这给了我们想要的输出

          Account Currency Credit_Code  Credit_Rate Debit_Code  Debit_Rate DB_Credit_Code  DB_Credit_Rate DB_Debit_Code  DB_Debit_Rate  Is_Reserve  Has_Reserve         CR_Match         Db_Match
    0  5551455514      GBP          CR         3.50         WW        -1.0             WW            3.50            WW           -1.0       False        False    NoMatchCredit     MatchOnDebit
    1  9631475400      USD          CE         0.00         FF         0.0             CE            1.25            FF            0.0       False         True  IgnoreHasCorAcc     MatchOnDebit
    2  8529875405      USD          CE         1.25         FF         0.0             CE            1.25            FF            0.0        True        False    MatchOnCredit     MatchOnDebit
    3  9631475400      EUR          CE         1.25         FF         0.0             CE            1.25            FF            0.0       False        False    MatchOnCredit     MatchOnDebit
    4  3265415409      USD          CE         1.25         FF         0.0             CE            1.25            FF            0.0       False        False    MatchOnCredit     MatchOnDebit
    5  9631475405      USD          CE         1.25         GG         0.0             CE            1.25            FF            0.0        True        False    MatchOnCredit  IgnoreHasCorAcc
    

    【讨论】:

    • 谢谢@saiden 完美。辛苦了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 2019-02-16
    相关资源
    最近更新 更多