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

时间:2020-09-21 16:56:29

标签: python python-3.x pandas

我有一个看起来像这样的DataFrame:

Khan: 63.0000% (2218231)
Correy: 20.0000% (704200)
Li: 14.0000% (492940)
O'Tooley: 3.0000% (105630)

当index_ [1 | 2 | 3 | 4]是MultiIndex时。 Something [1 | 2]是第一级列。 日期是重复的第二级列,在Something [1 | 2]第一级列中相同。

现在,我得到了另一个表,其中包含我想用当前表充实的值。 表如下:

                                     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'

我想用旧桌子充实旧桌子。

我的问题是:我如何使用新表填充旧表-当我只想在index_4 date val D0 2020-03-30 8 D0 2020-03-31 9 ... D1 2020-03-30 17 D1 2020-03-31 33 中设置值时,它看起来像(在日期{{ 1}}在Something1)中:

Something1

我尝试使用2020-03-31 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_value来设置值,但是我找不到正确的组合来到达正确的单元格。 (也在this帖子中查找了一些想法,但没有成功)
我想看起来像这样应该很

xs

2 个答案:

答案 0 :(得分:1)

我能想到的一种方法是重新整形数据,以便我们可以将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)

答案 1 :(得分:1)

  • 为了使用矢量化实现更新DataFrame,两个数据帧之间的列索引和行索引必须匹配。
  • 给出class FrozenModule(): def __init__(self, fake_data, callback): self.fake_data = fake_data self.match = 0 self.callback = callback def run(self): for x in range(10): if x == self.match: self.callback(x, self.fake_data[x]) df,如问题所示。问题的底部已设置了可重现的数据框。
  • 此实现避免使用df2,而使用pandas.DataFrame.update
  1. 将列级别添加到.apply,使其与df2的列级别相匹配
  2. df的索引重置为仅包含df中的索引
  3. df2更新df,然后根据需要重置索引。
df2

可重复的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