Pandas .map 字典默认缺失值

ffg*_*fgg 7 python dictionary missing-data pandas

pandas.Series.map 的Pandas 文档 说:

“当arg是字典时,Series中不在字典中的值(作为键)将转换为NaN。但是,如果字典是定义missing的dict子类(即提供默认值的方法),则此默认值使用而不是 NaN。”

你实际上是如何做到的?我无法让它工作..

class MyDict(collections.UserDict):
    
  def __missing__(self):
    return "_Unknown"

d = MyDict({k: v for k, v in my_list})

df.col1.map(d)

Run Code Online (Sandbox Code Playgroud)

ALo*_*llz 12

您需要(self, key)作为以下参数__missing__

class MyDict(dict):
    def __missing__(self, key):
        return "_Unknown"
Run Code Online (Sandbox Code Playgroud)
import pandas as pd

s = pd.Series(range(4))
d = {0: 'foo', 1: 'bar', 2: 'baz'}

s.map(MyDict(d))
#0         foo
#1         bar
#2         baz
#3    _Unknown
#dtype: object
Run Code Online (Sandbox Code Playgroud)

虽然这个功能很好,map但当它使用标准字典时,它是一种非常有效的 pandas 方法,但上面的方法会减慢它的速度(如下所示)。因此,您可以map使用普通的字典,然后链接到 a.fillna来处理默认值。

s.map(d).fillna('_Unknown')
#0         foo
#1         bar
#2         baz
#3    _Unknown
#dtype: object
Run Code Online (Sandbox Code Playgroud)

使用带有丢失键的特殊返回的字典与后跟.fillna. MyDict对于非常小的映射来说要快得多,但对于较大的系列来说则较慢。

import perfplot
import pandas as pd
import numpy as np

class MyDict(dict):
    def __missing__(self, key):
        return "_Unknown"

d = {0: 'foo', 1: 'bar', 2: 'baz'}  
d2 = MyDict(d)

def map_fillna(s, d):
    return s.map(d).fillna("_Unknown")

def use_MyDict(s, MyDict):
    return s.map(MyDict)


perfplot.show(
    setup=lambda n: pd.Series(np.random.choice(range(7), n)), 
    kernels=[
        lambda s: map_fillna(s, d),
        lambda s: use_MyDict(s, d2),
    ],
    labels=['map + fillna', 'MyDict'],
    n_range=[2 ** k for k in range(1, 27)],
    equality_check= lambda x,y: x.compare(y).empty,
    xlabel='len(s)'
)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述