Python 合并两列,同时优先考虑第一列

Python 合并两列,同时优先考虑第一列,python,pandas,dataframe,merge,nan,Python,Pandas,Dataframe,Merge,Nan,从中,我有两个矩阵,并希望以这样的方式合并它们:我将join-dfB放在dfA上,在任何地方用非NaN值替换NaN值 就是 >>> dfA s_name geo zip date value 0 A zip 60601 2010 NaN # In the earlier question, this was None 1 B zip 60601 2010 NaN # rather than NaN, which was

从中,我有两个矩阵,并希望以这样的方式合并它们:我将join-dfB放在dfA上,在任何地方用非NaN值替换NaN值

就是

>>> dfA
  s_name  geo    zip  date value
0      A  zip  60601  2010   NaN  # In the earlier question, this was None
1      B  zip  60601  2010   NaN  # rather than NaN, which was
2      C  zip  60601  2010   NaN  # a mistake.
3      D  zip  60601  2010   NaN

>>> dfB
  s_name  geo    zip  date  value
0      A  zip  60601  2010    1.0
1      B  zip  60601  2010    NaN
3      D  zip  60601  2010    4.0
合并它们,我看到:

>>> new = pd.merge(dfA,dfB,on=["s_name","geo", "geoid", "date"],how="left")
>>> new.head()
  name    geo   zip  date  value_x  value_y
0    A  state    01  2009      NaN      1.0
1    B  state    01  2010      NaN      NaN
2    C  state    01  2011      NaN      NaN
3    D  state    01  2012      NaN      4.0
4    E  state    01  2013      NaN      5.0
我不能确定值_y总是编号的,值_x总是NaN。但是我想要一个合并的值,称之为
value
,这是一个非NaN的值。我试试这个:

>>> new["value"] = new.apply(lambda r: r.value_x or r.value_y, axis=1)
>>> new.head()
  name    geo   zip  date  value_x  value_y  value
0    A  state    01  2009      NaN      1.0    NaN
1    B  state    01  2010      NaN      NaN    NaN
2    C  state    01  2011      NaN      NaN    NaN
3    D  state    01  2012      NaN      4.0    NaN
4    E  state    01  2013      NaN      5.0    NaN
哦,不

这是有道理的,因为NaN应该传播,但这不是我想要的。我希望逻辑能够返回存在的任何一个,而不是返回NaN(如果存在)

我喜欢没有人给我的逻辑。你可以看到:

>>> new["value_z"] = None
>>> new.head()
  name    geo   zip  date  value_x  value_y  value value_z
0    A  state    01  2009      NaN      1.0    NaN    None
1    B  state    01  2010      NaN      NaN    NaN    None
2    C  state    01  2011      NaN      NaN    NaN    None
3    D  state    01  2012      NaN      4.0    NaN    None
4    E  state    01  2013      NaN      5.0    NaN    None

>>> new["value2"] = new.apply(lambda r: r.value_z or r.value_y, axis=1)
>>> new.head()
  name    geo   zip  date  value_x  value_y  value value_z   value2
0    A  state    01  2009      NaN      1.0    NaN    None      1.0
1    B  state    01  2010      NaN      NaN    NaN    None      NaN
2    C  state    01  2011      NaN      NaN    NaN    None      NaN
3    D  state    01  2012      NaN      4.0    NaN    None      4.0
4    E  state    01  2013      NaN      5.0    NaN    None      5.0
创建
value2
的逻辑是我正在寻找的行为,而不是
value


最好的方法是什么

从技术上讲,这是通过敲定逻辑来实现的,但很难看,感觉像是一个黑客(我相信由于操作员短路,它会优先考虑value_x):

将在合并后工作:

dfC = pd.merge(dfA, dfB, on=["s_name", "geo", "zip", "date"], how="left")
dfC['value'] = dfC.pop('value_x').combine_first(dfC.pop('value_y'))
dfC

  s_name  geo    zip  date  value
0      A  zip  60601  2010    1.0
1      B  zip  60601  2010    NaN
2      C  zip  60601  2010    NaN
3      D  zip  60601  2010    4.0
combine_first
优先选择“value_x”而不是“value_y”。您也可以这样写:

dfC = pd.merge(dfA, dfB, on=["s_name", "geo", "zip", "date"], how="left")
dfC['value_x'] = dfC['value_x'].combine_first(dfC.pop('value_y'))
dfC

  s_name  geo    zip  date  value_x
0      A  zip  60601  2010      1.0
1      B  zip  60601  2010      NaN
2      C  zip  60601  2010      NaN
3      D  zip  60601  2010      4.0

如果您对
值_x
有偏好,您可以尝试:

df.value_x = df.value_x.fillna(df.value_y)
df.pop('value_y')
或:


如果
'value\ux'
'value\uy'
都有一个非
NaN
值,该怎么办?我对value\ux有偏好,但理论上不应该发生。如果两种方法都能解决,那太好了。你是说这个吗<代码>df.value\u x=df.value\u x.fillna(df.value\u y)?我不知道如何先组合,谢谢。)这很聪明。这被认为是惯用的吗?@Mittenchops是的,我想说,
combine_first
fillna
都是组合两个系列并在过程中填充NAN的同样好的选择。我先用了
combine\u
,因为那是你链接的另一篇文章。
df.value_x = df.value_x.fillna(df.value_y)
df.pop('value_y')
df.value_x=df.value_x.fillna(df.pop('value_y'))

>>df
   name geo    zip  date    value_x
0   A   state   1   2009    1.0
1   B   state   1   2010    NaN
2   C   state   1   2011    NaN
3   D   state   1   2012    4.0
4   E   state   1   2013    5.0