如何根据重复的 id 填充 NaN?

how to fill NaNs based on repeating id?

我有一个基本的 df - 一份贷款月度报告,它是每个日期(每月)给出的 1700 个贷款合同 ID 例如2019 年 1 月 1 日的报告:

contract_id    loan_sum   expiry_days_01_01_2019
  1            1000       20
  2            2300       3
  3            500        17
  4            1400       6
  5            890        5

2019 年 2 月 1 日的另一个

 contract_id loan_sum   expiry_days_01_02_2019
      1      7000       20
      2      3000       39
      3      500        130
      4      9400       89
      5      909        7

等等

我有 5 个 ID 数量相同的报告。我把它们合并在另一个下面了。

现在我有很多到期日期列的 nan 值,就像在一个矩阵中,对角线用 1 正确填充。

 id  contract_id     loan_sum   expiry_days_01_01_2019 expiry_01_02_2019
   0           1      7000       20                      nan
   1           2      3000       39                      nan
   2           3      500        130                     nan
   3           4      9400       89                      nan
   4           5      909        7                       nan
   5           1      7000       nan                     20
   6           2      3000       nan                     39
   7           3      500        nan                     130
   8           4      9400       nan                     89
   9           5      909        nan                     7
   ...           ...                     ...

当合同 ID 重复时,它应该提取相同的日期,但它们变成了 NaN。

如何根据相同、重复的合约 ID 填充 nan 值?

您可以先使用 groupby.transform。如果整个数据帧被称为 dfm,那么:

# I assumed you put the dataframes together like this
dfm = pd.concat([df1, df2], axis=0)

col_exp = dfm.filter(like='expiry').columns
dfm[col_exp] = dfm.groupby('contract_id')[col_exp].transform('first')
print (dfm)
   contract_id  loan_sum  expiry_days_01_01_2019  expiry_days_01_02_2019
0            1      1000                    20.0                    20.0
1            2      2300                     3.0                    39.0
2            3       500                    17.0                   130.0
3            4      1400                     6.0                    89.0
4            5       890                     5.0                     7.0
0            1      7000                    20.0                    20.0
1            2      3000                     3.0                    39.0
2            3       500                    17.0                   130.0
3            4      9400                     6.0                    89.0
4            5       909                     5.0                     7.0

但我认为改变整个数据框的构建方式可能是另一种解决方案并创建多索引列,例如:

list_dfs = [df1, df2]
dfm = pd.concat([df_.set_index('contract_id')
                    .rename(columns=lambda x: x.split('_')[0]) 
                 for df_ in list_dfs], 
                 keys=[df_.filter(like='expiry').columns[0][-10:]  
                       for df_ in list_dfs], 
                 axis=1)
print (dfm)
            01_01_2019        01_02_2019       
                  loan expiry       loan expiry
contract_id                                    
1                 1000     20       7000     20
2                 2300      3       3000     39
3                  500     17        500    130
4                 1400      6       9400     89
5                  890      5        909      7