合并具有不同索引的多个Series,对重复的索引求和

时间:2019-04-16 18:53:25

标签: python pandas numpy dataframe

假设我有三个系列

s1 = pd.Series(data=np.arange(5))
s2 = pd.Series(data=np.arange(5),index=np.arange(2,7))
s3 = pd.Series(data=np.arange(5),index=np.arange(5,10))

这是将它们合并为一系列的最有效方法,该序列将重复索引中的data值相加,并将值保留在非重复索引中。换句话说,对于s1s2s3,我们期望输出:

0    0
1    1
2    2
3    4
4    6
5    3
6    5
7    2
8    3
9    4

实际上,我们可能会有大量带有大量数据条目的序列,因此循环效率不高。

2 个答案:

答案 0 :(得分:4)

让我们在这里使用concatsum

pd.concat([s1, s2, s3]).sum(level=0)

0    0
1    1
2    2
3    4
4    6
5    3
6    5
7    2
8    3
9    4
dtype: int64

串联是O(n)运算(线性复杂度),建议在99%的时间内进行。


如果您喜欢方法链接,那么这个适合您。

s1.append(s2).append(s3).sum(level=0)

0    0
1    1
2    2
3    4
4    6
5    3
6    5
7    2
8    3
9    4
dtype: int64

不建议用于3个以上的系列。一次添加两个,结果复杂度是二次方。

答案 1 :(得分:3)

这里有NumPy工具-

def sum_series(L): # L is list of series
    aL = [list(l.index) for l in L]
    intL,unqL = pd.factorize(np.concatenate(aL))
    sums = np.bincount(intL,np.concatenate(L))
    return pd.Series(sums, index=unqL)

样品运行-

In [158]: L = [s1,s2,s3] # list of series

In [159]: sum_series(L)
Out[159]: 
0    0.0
1    1.0
2    2.0
3    4.0
4    6.0
5    3.0
6    5.0
7    2.0
8    3.0
9    4.0
dtype: float64

带有通用标签-

In [170]: L
Out[170]: 
[Label0    0
 Label1    1
 Label2    2
 Label3    3
 Label4    4
 dtype: int64, Label2    0
 Label3    1
 Label4    2
 Label5    3
 Label6    4
 dtype: int64, Label5    0
 Label6    1
 Label7    2
 Label8    3
 Label9    4
 dtype: int64]

In [171]: sum_series(L)
Out[171]: 
Label0    0.0
Label1    1.0
Label2    2.0
Label3    4.0
Label4    6.0
Label5    3.0
Label6    5.0
Label7    2.0
Label8    3.0
Label9    4.0
dtype: float64

版本2

通过对数组数据进行串联并使用智能输出dtype,可能会通过类似以下方式获得更理想的输出-

def sum_series_v2(L): # L is list of series
    aL = [list(l.index) for l in L]
    v = [l.values for l in L]
    intL,unqL = pd.factorize(np.concatenate(aL))
    sums = np.bincount(intL,np.concatenate(v))
    dtype = np.result_type(*[l.dtype for l in L])
    return pd.Series(sums.astype(dtype), index=unqL)

样品运行-

In [225]: sum_series_v2(L)
Out[225]: 
Label0    0
Label1    1
Label2    2
Label3    4
Label4    6
Label5    3
Label6    5
Label7    2
Label8    3
Label9    4
dtype: int64