【问题标题】:Is there a "stack and map" analogue with dicts?是否有带有字典的“堆栈和地图”类似物?
【发布时间】:2018-10-06 07:46:37
【问题描述】:

我最近不得不将 dict 键映射到评估问题中的值。我从以下开始:

files=
{'Code.py': 'Stan', 'Output.txt': 'Randy', 'Input.txt': 'Randy'}

并将文件映射到其所有者,为此我使用了以下内容:

mapped={
        name:[key for key,value in files.items() if value==name]
        for name in list(set([value for key,value in files.items()]))
        }

这给了我在mapped 字典中想要的东西:

{'Stan': ['Code.py'], 'Randy': ['Output.txt', 'Input.txt']}

我只是想知道是否有更类似于 Pandas 的方式来做同样的事情,但使用普通字典。

【问题讨论】:

    标签: python python-3.x pandas dictionary mapping


    【解决方案1】:

    你可以使用defaultdict:

    from collections import defaultdict
    mapped = defaultdict(list)
    ​
    for k, v in files.items():
        mapped[v].append(k)
    
    mapped
    # defaultdict(list, {'Stan': ['Code.py'], 'Randy': ['Output.txt', 'Input.txt']})
    

    或者在字典上使用setdefault方法:

    mapped = {}
    ​
    for k, v in files.items():
        mapped.setdefault(v, []).append(k)
    
    mapped
    # {'Stan': ['Code.py'], 'Randy': ['Output.txt', 'Input.txt']}
    

    或者,如果您更喜欢pandas(但是,这对于此任务来说效率不高):

    s = pd.Series(files)
    s.groupby(s).agg(lambda x: x.index.tolist()).to_dict()
    # {'Randy': ['Input.txt', 'Output.txt'], 'Stan': ['Code.py']}
    

    小样本数据的时序:

    %%timeit
    from collections import defaultdict
    mapped = defaultdict(list)
    ​
    for k, v in files.items():
        mapped[v].append(k)
    # 2 µs ± 33.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    
    %%timeit
    s = pd.Series(files)
    s.groupby(s).agg(lambda x: x.index.tolist()).to_dict()
    # 2.12 ms ± 54.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    

    【讨论】:

    • 这是一个很好的答案。如果像许多评估中的情况一样,我无法进行任何导入怎么办?
    • 在普通字典上使用setdefault应该和defaultdict一样工作。
    • 有什么方法可以迭代 python3 map 对象,它比使用 any() 更健壮吗?关于我问的原因,请参阅下面的答案。
    猜你喜欢
    • 1970-01-01
    • 2014-03-04
    • 1970-01-01
    • 2010-11-13
    • 1970-01-01
    • 1970-01-01
    • 2013-12-09
    • 2013-02-12
    • 1970-01-01
    相关资源
    最近更新 更多