如何从另一个数据帧更新多索引数据帧?

2024-10-03 13:28:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据框,看起来像:

                                     Something1                        Something2 
                              date  2020-03-30  2020-03-31  2020-04-01  2020-03-30  2020-03-31  2020-04-01  
index_1 index_2  index_3 index_4                                                                                    
A0        B0       C0        D0         10         NaN         11         'bla'          'bli'    'blo'
A1        B1       C1        D1         8          NaN         NaN        'bla1'         'bli1    'blo1'
A2        B2       C2        D0         0          NaN         303        'bla2'         'bli2'   'blo2'

当索引[1 | 2 | 3 | 4]是多索引时。 有些东西[1 | 2]是第一级列。 日期是重复的第二级列,它们在[1 | 2]的第一级列中是相同的

现在,我得到了一个不同的表,其中包含我想用当前表来充实的值。 新的表格如下所示:

index_4      date          val  
   D0      2020-03-30      8
   D0      2020-03-31      9
   ...
   D1      2020-03-30      17
   D1      2020-03-31      33

我想用那张旧桌子来充实这张旧桌子

我的问题是:如何使用新表填充旧表-当我只想在Something1中设置值时,它看起来像(在某物的日期2020-03-31中填充D0之后):

                                     Something1                        Something2 
                              date  2020-03-30  2020-03-31  2020-04-01  2020-03-30  2020-03-31  2020-04-01  
index_1 index_2  index_3 index_4                                                                                    
A0        B0       C0        D0         10         9           11       'bla'          'bli'      'blo'
A1        B1       C1        D1         8          NaN         NaN      'bla1'         'bli1'     'blo1'
A2        B2       C2        D0         0          9           303      'bla2'         'bli2'     'blo2'

我尝试使用set_valuexsat设置值,但找不到正确的组合以到达正确的单元格。(也在this帖子中寻找了一些想法,但没有成功)
我想应该是这样的

df.at[index_4='D0']['Something1']['2020-03-31'] = new_df['D0', '2020-03-31']['val']

Tags: dateindexa1nanb0a0b1d1
2条回答

我能想到的一种方法是重塑数据,这样我们就可以将index_4date作为索引,映射值,然后重新重塑:

df2 = df2.set_index(['date','index_4'])

s = df['S1'].unstack(level=-1).T
df['S1'] = s.apply(lambda x: x.fillna(df2['val'])).T.stack(level=-1)
  • 为了使用矢量化实现更新数据帧,两个数据帧之间的列和行索引必须匹配
  • 给定dfdf2,如问题所示。在问题的底部设置了可复制的数据帧
  • 此实现避免使用.apply,而是使用^{}
  1. df2添加列级别,使其与df的列级别匹配
  2. 重置df的索引以仅包含df2中的索引
  3. df2更新df,并根据需要重置索引
import pandas

# set the column index of df2 to have a matching level 0
df2.columns = pd.MultiIndex.from_product([['S1'], df2.columns])

# display(df2)
                         S1           
      2020-03-30 2020-03-31
idx4                       
D0             8          9
D1            17         33

# reset the index of dfg so only idx4 is in the index
df = df.reset_index(level=[0, 1, 2])

# update the df from df2
df.update(df2, overwrite=False)
df = df.reset_index().set_index(['idx1', 'idx2', 'idx3', 'idx4'], append=True)

# display(df)
                                                    S1                               S2                      
                      2020-03-30 2020-03-31 2020-04-01 2020-03-30 2020-03-31 2020-04-01
  idx1 idx2 idx3 idx4                                                                  
0 A0   B0   C0   D0           10          9         11        bla        bli        blo
1 A1   B1   C1   D1            8         33        NaN       bla1       bli1       blo1
2 A2   B2   C2   D0            0          9        303       bla2       bli2       blo2

可复制的df2设置

df2 = pd.DataFrame.from_dict({'D0': {'2020-03-30': 8, '2020-03-31': 9}, 'D1': {'2020-03-30': 17, '2020-03-31': 33}}, 'index')
df2.index.names = ['idx4']

# display(df2)
       2020-03-30  2020-03-31
idx4                         
D0              8           9
D1             17          33

可复制的df设置

data = {('A0', 'B0', 'C0', 'D0'): {('S1', '2020-03-30'): '10', ('S1', '2020-03-31'): pd.NA, ('S1', '2020-04-01'): '11', ('S2', '2020-03-30'): 'bla', ('S2', '2020-03-31'): 'bli', ('S2', '2020-04-01'): 'blo'},
        ('A1', 'B1', 'C1', 'D1'): {('S1', '2020-03-30'): '8', ('S1', '2020-03-31'): pd.NA, ('S1', '2020-04-01'): pd.NA, ('S2', '2020-03-30'): 'bla1', ('S2', '2020-03-31'): 'bli1', ('S2', '2020-04-01'): 'blo1'},
        ('A2', 'B2', 'C2', 'D0'): {('S1', '2020-03-30'): '0', ('S1', '2020-03-31'): pd.NA, ('S1', '2020-04-01'): '303', ('S2', '2020-03-30'): 'bla2', ('S2', '2020-03-31'): 'bli2', ('S2', '2020-04-01'): 'blo2'}}

df = pd.DataFrame.from_dict(data, 'index')
df.index.names = ['idx1', 'idx2', 'idx3', 'idx4']

                                                  S1                               S2                      
                    2020-03-30 2020-03-31 2020-04-01 2020-03-30 2020-03-31 2020-04-01
idx1 idx2 idx3 idx4                                                                  
A0   B0   C0   D0           10       <NA>         11        bla        bli        blo
A1   B1   C1   D1            8       <NA>       <NA>       bla1       bli1       blo1
A2   B2   C2   D0            0       <NA>        303       bla2       bli2       blo2

相关问题 更多 >