【问题标题】:pandas: merge on column of collections.Counter (or even just dict) objects?熊猫:合并列集合。计数器(甚至只是字典)对象?
【发布时间】:2015-09-18 22:25:59
【问题描述】:

我需要使用带有collections.Counter 对象 (https://docs.python.org/2/library/collections.html#collections.Counter) 的列来合并两个 pandas DataFrame。合并引发了一个奇怪的错误。请参阅下面的可执行代码示例。

import pandas as pd
from collections import Counter
a = pd.DataFrame([(120000.0, 120000.0, 0.0, 120000.0),
 (120000.0, 280000.0, 120000.0, 120000.0),
 (280000.0, 280000.0, 120000.0, 280000.0),
 (280000.0, 420000.0, 280000.0, 280000.0),
 (420000.0, 420000.0, 280000.0, 420000.0),
 (420000.0, 500000.0, 420000.0, 420000.0),
 (500000.0, 580000.0, 420000.0, 500000.0),
 (580000.0, 820000.0, 500000.0, 580000.0),
 (820000.0, 860000.0, 580000.0, 820000.0),
 (860000.0, 1160000.0, 820000.0, 860000.0),
 (1160000.0, 1160000.0, 860000.0, 1160000.0)])
b = pd.DataFrame([(120000.0, 120000.0, 0.0, 120000.0),
 (120000.0, 280000.0, 120000.0, 120000.0),
 (280000.0, 280000.0, 120000.0, 280000.0),
 (280000.0, 440000.0, 280000.0, 280000.0),
 (440000.0, 440000.0, 280000.0, 440000.0),
 (440000.0, 520000.0, 440000.0, 440000.0),
 (520000.0, 580000.0, 440000.0, 520000.0),
 (580000.0, 820000.0, 520000.0, 580000.0),
 (820000.0, 860000.0, 580000.0, 820000.0),
 (860000.0, 1120000.0, 820000.0, 860000.0),
 (1120000.0, 1160000.0, 860000.0, 1120000.0)])
a['ID'] = [Counter(i) for i in list(a.values)]
b['ID'] = [Counter(i) for i in list(b.values)]
pd.merge(a, b, on='ID')

这会返回:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 601, in runfile
    execfile(filename, namespace)
  File "/usr/local/lib/python2.7/dist-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 73, in execfile
    builtins.execfile(filename, *where)
  File "/home/ilya/tmp/tmp_merge.py", line 33, in <module>
    pd.merge(a, b, on='ID')
  File "/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.py", line 38, in merge
    return op.get_result()
  File "/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.py", line 186, in get_result
    join_index, left_indexer, right_indexer = self._get_join_info()
  File "/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.py", line 273, in _get_join_info
    sort=self.sort, how=self.how)
  File "/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.py", line 461, in _get_join_indexers
    llab, rlab, shape = map(list, zip( * map(fkeys, left_keys, right_keys)))
TypeError: type object argument after * must be a sequence, not itertools.imap

我尝试将 Counter 对象转换为普通字典(即

b['ID'] = [dict(Counter(i)) for i in list(b.values)]

),但它没有帮助。这是正常行为吗?如果是,我该如何规避这个错误?或者有没有其他方法可以达到相同的最终结果?

我使用 python 2.7 和 pandas 0.16.1(通常是 ipython notebook,但也只在 python 中测试过)。

编辑: 澄清这一切是为了什么。 我需要根据两对列的值进行合并。在实际数据中,它们是 Start1、End1、Start2、End2。结束2>开始2,结束1>开始1。这个例子是我真实价值观的一个子集。问题是在两个数据集中可能会出现 (Start1_1, End1_1)==(Start2_2, End2_2) and (Start1_2, End1_2)==(Start2_1, End2_1);我也希望将这些行合并(第二个数字表示数据集)。我认为使用这样的计数器应该是最简单的解决方案,而且我很确定这种方式不会出现误报。

【问题讨论】:

  • 你确定你在尝试散列字典时没有收到错误吗?
  • 也许,我不知道...
  • 你到底想做什么?
  • 请看编辑。

标签: python pandas merge


【解决方案1】:

解决此问题的一种方法是(为每个 DataFrame)创建一个将原始数据结构版本转换为可散列类型的列。

例如,

a['IDHash'] = a.ID.apply(lambda r: tuple(sorted(r.iteritems())))
b['IDHash'] = b.ID.apply(lambda r: tuple(sorted(r.iteritems())))

然后

pd.merge(a, b, on='IDHash')

之后,只需擦除列。

【讨论】:

    猜你喜欢
    • 2019-02-24
    • 2021-03-13
    • 1970-01-01
    • 2020-11-23
    • 2017-04-17
    • 2021-01-08
    • 2015-04-08
    • 2021-04-28
    • 2016-10-31
    相关资源
    最近更新 更多