pandas concat/merge和sum一列

Joh*_*ohn 2 python pandas

我有两个pandas.DataFrameMultiIndex索引的对象.一些索引值与两个数据帧共享,但不是全部.我想合并这两个数据帧,如果行(索引值)存在,则取其中一列的总和.否则,保持行和列值不变.

:这很接近,但不使用MultiIndex

我试图创建一个例子:

def mklbl(prefix,n):
try:
    return ["%s%s" % (prefix,i)  for i in range(n)]
except:
    return ["%s%s" % (prefix,i) for i in n]



mi1 = pd.MultiIndex.from_product([mklbl('A',4), mklbl('C',2)])

mi2 = pd.MultiIndex.from_product([mklbl('A',[2,3,4]), mklbl('C',2)])

df2 = pd.DataFrame({'b':np.arange(len(mi2)), 'c':np.arange(len(mi2))[::-1]},
      index=mi2).sort_index().sort_index(axis=1)

df1 = pd.DataFrame({'a':np.arange(len(mi1)), 'b':np.arange(len(mi1))[::-1]},
      index=mi1).sort_index().sort_index(axis=1)
Run Code Online (Sandbox Code Playgroud)

各个DataFrame对象看起来像:

In [117]: df1
Out[117]: 
       a  b
A0 C0  0  7
   C1  1  6
A1 C0  2  5
   C1  3  4
A2 C0  4  3
   C1  5  2
A3 C0  6  1
   C1  7  0
Run Code Online (Sandbox Code Playgroud)

In [118]: df2
Out[118]: 
       b  c
A2 C0  0  5
   C1  1  4
A3 C0  2  3
   C1  3  2
A4 C0  4  1
   C1  5  0
Run Code Online (Sandbox Code Playgroud)

我想要做的是合并这两个,并加上'b'列,但保留所有行,无论它们是否存在于一个或另一个数据帧中:

In [117]: df_merged_bsummed
Out[117]: 
       a  b  c
A0 C0  0  7  NaN
   C1  1  6  NaN
A1 C0  2  5  NaN
   C1  3  4  NaN
A2 C0  4  3  5
   C1  5  3  4
A3 C0  6  3  3
   C1  7  3  2
A4 C0  NaN 4  1
   C1  NaN 5  0
Run Code Online (Sandbox Code Playgroud)

DSM*_*DSM 5

在这种特殊情况下,我认为您可以添加它们并使用fill_value=0,依赖于默认的对齐行为:

>>> df1.add(df2,fill_value=0)
        a  b   c
A0 C0   0  7 NaN
   C1   1  6 NaN
A1 C0   2  5 NaN
   C1   3  4 NaN
A2 C0   4  3   5
   C1   5  3   4
A3 C0   6  3   3
   C1   7  3   2
A4 C0 NaN  4   1
   C1 NaN  5   0
Run Code Online (Sandbox Code Playgroud)

只有一个共同的列,只有一个是相加的,但是如果你想明确这一点,你可以做一些类似的事情

>>> m = pd.concat([df1, df2],axis=1)
>>> m["b"] = m.pop("b").sum(axis=1)
>>> m
        a   c  b
A0 C0   0 NaN  7
   C1   1 NaN  6
A1 C0   2 NaN  5
   C1   3 NaN  4
A2 C0   4   5  3
   C1   5   4  3
A3 C0   6   3  3
   C1   7   2  3
A4 C0 NaN   1  4
   C1 NaN   0  5
Run Code Online (Sandbox Code Playgroud)