【问题标题】:Why doesn't replace work with a dictionary with tuples as the key?为什么不使用以元组为键的字典替换工作?
【发布时间】:2018-12-20 21:20:59
【问题描述】:

我一直认为.map.replace 本质上是相同的,除了当你想传递不在提供的字典中的键值时你会使用.replace。但是,我很困惑为什么 .replace 在传递以元组为键的字典时会抛出 TypeError ,而 .map 在同一字典中按预期工作。

例如:

import pandas as pd
df = pd.DataFrame({'ID1': [1, 2, 3, 4, 5], 
                   'ID2': ['A', 'B', 'C', 'D', 'E']})
df['tup_col'] = pd.Series(list(zip(df.ID1, df.ID2)))

dct = {(1, 'A'): 'apple', (3, 'C'): 'banana', (5, 'X'): 'orange'}

df.tup_col.map(dct)
#0     apple
#1       NaN
#2    banana
#3       NaN
#4       NaN
#Name: tup_col, dtype: object

df.tup_col.replace(dct)

TypeError:无法比较类型 'ndarray(dtype=object)' 和 'tuple'

那么对于以元组作为键的字典,我可以不使用replace 吗?

【问题讨论】:

  • 查看文档,功能不相关。 replace 似乎与 apply 相关,而不是 map。该文档还说您可以使用嵌套字典,但是在您的示例中尝试我得到“元组没有方法替换”,所以这也不起作用。

标签: python pandas dictionary series


【解决方案1】:

不,这行不通

首先 Pandas 从您的字典中获取键和值,然后使用这些可迭代对象调用 replace

keys, values = zip(*items)
to_replace, value = keys, values

return self.replace(to_replace, value, inplace=inplace,
                    limit=limit, regex=regex)

接下来,由于您现在拥有 list_like 键和值,它会输入到replace_list

elif is_list_like(to_replace):  # [NA, ''] -> [0, 'missing']
    if is_list_like(value):
        new_data = self._data.replace_list(src_list=to_replace, dest_list=value,
                                           inplace=inplace, regex=regex)

接下来,replace_list 尝试在元组数组和值数组之间进行比较:

def comp(s):
    if isnull(s):
        return isnull(values)
    return _possibly_compare(values, getattr(s, 'asm8', s),
                             operator.eq)

masks = [comp(s) for i, s in enumerate(src_list)]

最后,_possibly_compare 检查值是否由标量组成,而键是类似数组的,从而导致错误:

if is_scalar(result) and (is_a_array or is_b_array):
    raise TypeError("Cannot compare types %r and %r" % tuple(type_names))

我在这里排除了一些位,可能是重要的位。但希望你能明白要点。

结论

在我看来,pd.Series.replace 有严重的问题。与大多数 Pandas API 不同,它的实现和性能通常是不可预测的。很明显,它的块是用纯 Python 编写的,性能不佳。

documentation 很好地总结了歧义:

这种方法有很多选择。我们鼓励您尝试并 尝试使用这种方法来直观了解它的工作原理。

pd.Series.map 是高效的,不会受到replace 中实现的纯 Python 逻辑的影响。

另一个例子见Replace values in a pandas series via dictionary efficiently

坚持map,不要回头看replace

【讨论】:

  • 哇,感谢您的精彩解释!您在映射链接中的其他答案以及在另一列中的fillna 几乎正是我想要的!
猜你喜欢
  • 1970-01-01
  • 2022-06-14
  • 2020-09-25
  • 1970-01-01
  • 2010-11-28
  • 1970-01-01
  • 2010-12-28
  • 1970-01-01
  • 2011-12-25
相关资源
最近更新 更多