如何避免Pandas.Merge上的多列

时间:2016-02-08 17:45:40

标签: python pandas

想象一下,我在Pandas上有以下DataFrame:

Traceback (most recent call last):
File "C:\Python27\Lib\runpy.py", line 162, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "C:\Python27\Lib\runpy.py", line 72, in _run_code
exec code in run_globals
File "C:\Python27\Scripts\pip.exe\__main__.py", line 5, in <module>
File "C:\Python27\lib\site-packages\pip\__init__.py", line 15, in <module>
from pip.vcs import git, mercurial, subversion, bazaar  # noqa
File "C:\Python27\lib\site-packages\pip\vcs\mercurial.py", line 9, in <module>
from pip.download import path_to_url
File "C:\Python27\lib\site-packages\pip\download.py", line 38, in <module>
from pip._vendor import requests, six
File "C:\Python27\lib\site-packages\pip\_vendor\requests\__init__.py", line 58, in <module>
from . import utils
File "C:\Python27\lib\site-packages\pip\_vendor\requests\utils.py", line 26, in <module>
from .compat import parse_http_list as _parse_list_header
File "C:\Python27\lib\site-packages\pip\_vendor\requests\compat.py", line 7, in <module>
from .packages import chardet
File "C:\Python27\lib\site-packages\pip\_vendor\requests\packages\__init__.py", line 29, in <module>
import urllib3
ImportError: No module named urllib3

但我想要的是(基本上避免重复列):

In [7]: A= pd.DataFrame([['foo'],['bar'],['quz'],['baz']],columns=['key'])

In [8]: A['value'] = 'None'

In [9]: A
Out[9]:
   key value
0  foo  None
1  bar  None
2  quz  None
3  baz  None

In [10]: B = pd.DataFrame([['foo',5],['bar',6],['quz',7]],columns= ['key','value'])

In [11]: B
Out[11]:
   key  value
0  foo      5
1  bar      6
2  quz      7

In [12]: pd.merge(A,B, on='key', how='outer')
Out[12]:
   key value_x  value_y
0  foo    None        5
1  bar    None        6
2  quz    None        7
3  baz    None      NaN

我想我可以获取输出并删除 key value 0 foo 5 1 bar 6 2 quz 7 3 baz NaN 值并重命名_x,但这似乎有点矫枉过正。在SQL上,这将是微不足道的。

编辑:

John建议使用:

_y

这符合我的要求。

1 个答案:

答案 0 :(得分:1)

在示例中,您要合并两个具有相同列的数据帧,一个包含字符串(&#39;无&#39;)其他整数,pandas不知道您要保留哪个列值以及哪个应该保留哪个列值被替换,因此它为两者创建了一个列。

您可以使用update代替

In [10]: A.update(B, join='left', overwrite=True)
In [11]: A
Out[11]:

    key value
0   foo 5
1   bar 6
2   quz 7
3   baz NaN

另一种解决方案是仅为给定列声明所需的值:

In [15]: A.loc[B.index, 'value'] = B.value
In [16]: A
Out[16]:

    key value
0   foo 5
1   bar 6
2   quz 7
3   baz NaN

就我个人而言,我更喜欢第二种解决方案,因为我确切知道发生了什么,但第一种可能更接近您在问题中寻找的内容。

编辑:

如果指数不匹配,我不太确定如何实现这一点。因此我建议将它们匹配:

In [1]: A.set_index('key', inplace=True)
        A.update(B.set_index('key'), join='left', overwrite=True)
        A.reset_index(inplace=True)

可能有更好的方法可以做到这一点,但我不相信大熊猫有办法直接执行此操作。

第二个解决方案也可以与更新的索引一起使用:

In [24]: A.set_index('key', inplace=True)
         A.loc[B.key, 'value'] = B.value.tolist()