代码之家  ›  专栏  ›  技术社区  ›  ALollz

为什么不用以元组为键的字典替换工作?

  •  1
  • ALollz  · 技术社区  · 6 年前

    我一直认为 .map .replace 基本上是一样的,除了你会用 .更换 当要传递不在提供的字典中的键的值时。但是,我不明白为什么 .更换 抛出一个 TypeError 当传递以元组为键的字典时, 地图 使用同一个词典时,按预期工作。

    例如:

    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)
    

    类型错误:无法比较类型“ndarray(dtype=object)”和“tuple”

    所以我不能用 replace 以元组为键的字典为例?

    1 回复  |  直到 6 年前
        1
  •  2
  •   jpp    6 年前

    不,这样不行

    首先,熊猫从你的字典中获取键和值,然后调用 replace 有了这些iTerables:

    keys, values = zip(*items)
    to_replace, value = keys, values
    
    return self.replace(to_replace, value, inplace=inplace,
                        limit=limit, regex=regex)
    

    下一步,因为您现在有了类似列表的键和值,它将输入 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)
    

    下一步, 替换\u列表 尝试在元组数组和值数组之间执行比较:

    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 是有效的,并且不受中实现的纯Python逻辑的影响 代替 .

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

    坚持 map 别回头看 代替 .