根据值对齐两个系列

时间:2019-06-24 18:51:59

标签: python pandas

我正在尝试将两个系列中的数据对齐,并找出每个系列中的漏洞。我有一个解决方案,正在寻找是否有更好的方法可以做到这一点。

示例

Series 1                  Series 2
A                         B
B                         C
D                         D

Output
A     
B     B
      C
D     D

我的解决方案

import pandas as pd
import numpy as np
x = pd.Series( np.arange(3), index=['A', 'B', 'D'] )
y = pd.Series( np.arange(3), index=['B', 'C', 'D'] )
Z = pd.concat([x,y], axis=1)                            # Align by index
Z1 = Z[0].reset_index().rename({'index': 'x'}, axis=1)
Z1.loc[Z1[0].isna(), 'x'] = ''
Z2 = Z[1].reset_index().rename({'index': 'y'}, axis=1)
Z2.loc[Z2[1].isna(), 'y'] = ''
pd.concat([ Z1['x'], Z2['y'] ], axis=1)

输出

Out[67]:
   x  y
0  A
1  B  B
2     C
3  D  D

3 个答案:

答案 0 :(得分:2)

由于这些系列的索引中包含A,B,C,D,因此我宁愿返回该值,而不是将其作为值:

In [11]: pd.DataFrame.from_dict({"x": x, "y": y})
Out[11]:
     x    y
A  0.0  NaN
B  1.0  0.0
C  NaN  1.0
D  2.0  2.0

In [12]: pd.DataFrame.from_dict({"x": x, "y": y}).isnull()
Out[12]:
       x      y
A  False   True
B  False  False
C   True  False
D  False  False

答案 1 :(得分:1)

in的理解

xy = sorted(x.index | y.index)
pd.DataFrame(dict(
    x=[a if a in x.index else '' for a in xy],
    y=[b if b in y.index else '' for b in xy]
))

   x  y
0  A   
1  B  B
2     C
3  D  D

align的理解

pd.DataFrame(dict(
    zip('xy', map(lambda s: [k if pd.notna(v) else '' for k, v in s.items()], x.align(y)))
))

   x  y
0  A   
1  B  B
2     C
3  D  D

答案 2 :(得分:1)

让我们先使用pd.factorizeunion索引,然后再使用由pd.concat生成的索引来新建pd.Series map

mapper = dict(zip(*pd.factorize(x.index.union(y.index))[::-1]))

pd.concat([pd.Series(x.index, x.index.map(mapper), name='x'), 
           pd.Series(y.index, y.index.map(mapper), name='y')], axis=1).fillna('')

输出:

   x  y
0  A   
1  B  B
2     C
3  D  D

或者我们可以使用pd.Index.to_series代替pd.Series构造函数:

mapper = dict(zip(*pd.factorize(x.index.union(y.index))[::-1]))

pd.concat([x.index.to_series(x.index.map(mapper), name='x'), 
           y.index.to_series(y.index.map(mapper), name='y')], axis=1).fillna('')

输出:

   x  y
0  A   
1  B  B
2     C
3  D  D

我喜欢@piRSquared将alignpd.Index.to_series一起使用

使用align的@piRSquared想法,我们可以得出一个整齐的单线代码:

pd.concat(x.index.to_series(name='x').align(y.index.to_series(name='y')), axis=1)\
  .reset_index(drop=True).fillna('')

输出:

   x  y
0  A   
1  B  B
2     C
3  D  D