Python 合并两列,同时优先考虑第一列
从中,我有两个矩阵,并希望以这样的方式合并它们:我将join-dfB放在dfA上,在任何地方用非NaN值替换NaN值 就是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
>>> 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