当前位置: 首页 > 面试题库 >

Python-通过字典有效替换熊猫系列中的值

倪德业
2023-03-14
问题内容

如何s通过字典替换熊猫系列中的值d已被询问并多次提出。

推荐的方法(1,2,3,4)是要么使用s.replace(d),有时也使用s.map(d)如果所有的系列值是在字典键找到。

但是,使用性能的s.replace速度通常不合理,通常比简单的列表理解速度慢5-10倍。

替代方法s.map(d)具有良好的性能,但是仅当在字典中找到所有键时才建议使用。

为什么s.replace这么慢,如何提高性能?

import pandas as pd, numpy as np

df = pd.DataFrame({'A': np.random.randint(0, 1000, 1000000)})
lst = df['A'].values.tolist()

##### TEST 1 #####

d = {i: i+1 for i in range(1000)}

%timeit df['A'].replace(d)                          # 1.98s
%timeit [d[i] for i in lst]                         # 134ms

##### TEST 2 #####

d = {i: i+1 for i in range(10)}

%timeit df['A'].replace(d)                          # 20.1ms
%timeit [d.get(i, i) for i in lst]                  # 243ms

注意:此问题未标记为重复问题,因为它正在寻找有关在给定不同数据集的情况下何时使用不同方法的具体建议。这在答案中是明确的,并且是其他问题通常未解决的一个方面。


问题答案:

一个简单的解决方案是选择一种方法,该方法取决于对字典键完全覆盖值的估计。

一般情况

  • df[‘A’].map(d)如果所有值都已映射,则使用;否则 要么
  • df[‘A’].map(d).fillna(df[‘A’]).astype(int)如果映射的值大于5%,则使用。

  • d中的值很少,例如<5%

  • 采用 df['A'].replace(d)

〜5%的“交叉点”特定于以下基准测试。

有趣的是,map在任何一种情况下,简单的列表理解通常都表现不佳。

标杆管理

import pandas as pd, numpy as np

df = pd.DataFrame({'A': np.random.randint(0, 1000, 1000000)})
lst = df['A'].values.tolist()

##### TEST 1 - Full Map #####

d = {i: i+1 for i in range(1000)}

%timeit df['A'].replace(d)                          # 1.98s
%timeit df['A'].map(d)                              # 84.3ms
%timeit [d[i] for i in lst]                         # 134ms

##### TEST 2 - Partial Map #####

d = {i: i+1 for i in range(10)}

%timeit df['A'].replace(d)                          # 20.1ms
%timeit df['A'].map(d).fillna(df['A']).astype(int)  # 111ms
%timeit [d.get(i, i) for i in lst]                  # 243ms

说明

之所以s.replace这么慢,是因为它所做的不仅仅是映射字典。它处理一些极端情况和可能很少见的情况,这些情况通常在任何情况下都应格外小心。

这是replace()in的摘录pandas\generic.py

items = list(compat.iteritems(to_replace))
keys, values = zip(*items)
are_mappings = [is_dict_like(v) for v in values]

if any(are_mappings):
    # handling of nested dictionaries
else:
    to_replace, value = keys, values

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

似乎涉及许多步骤:

  • 将字典转换为列表。
  • 遍历列表并检查嵌套字典。
  • 将键和值的迭代器输入到替换函数中。

可以将其与来自map()中的更精简的代码进行比较pandas\series.py:

if isinstance(arg, (dict, Series)):
    if isinstance(arg, dict):
        arg = self._constructor(arg, index=arg.keys())

    indexer = arg.index.get_indexer(values)
    new_values = algos.take_1d(arg._values, indexer)


 类似资料:
  • 问题内容: 我知道这个问题有很多主题,但是没有一种方法适合我,因此我将发布有关我的具体情况的信息 我有一个看起来像这样的数据框: 我想做的是将“性别”列中的全0替换为“女”,并将所有1替换为“男”,但是当我使用上面的代码时,数据框中的值似乎没有变化 我是否使用了replace()错误?还是有更好的方法进行条件值替换? 问题答案: 是的,您使用的是错误的,默认情况下不是就地操作,它会返回替换的数据框

  • 问题内容: 鉴于熊猫0.20.0的更新和弃用,我想知道用其余的和获得相同结果的最有效方法是什么。我只是回答了这个问题,但是第二种选择(不使用)似乎效率低下且冗长。 片段: 同时使用条件和索引位置过滤时,这是正确的方法吗? 问题答案: 通过用位置对特定索引进行切片来获得所需的索引值,您可以留在一个单一的世界中。

  • 第一科伦:武器 第二栏:Pepetrator_年龄 例如,y轴应该是案件数量x轴犯罪人的年龄 线是犯罪者使用的武器类型 您可以将其复制粘贴到jupyter以初始化数据集 此处的数据集:https://www.kaggle.com/jyzaguirre/us-homicide-reports

  • 问题内容: 我想替换列中的子字符串 到。 需求输出 我尝试,但它返回。 问题答案: 使用与更换和:

  • 我有两个非常大的系列,只包含连接键。在不使用索引的情况下(在本例中没有意义),我希望以最有效的方式通过值将一个系列左键连接到另一个系列。 现在,我添加了一列1,这样我就可以使用和一个左连接,这样我就可以确定中的每个键是否也存在于Right中。 我确信我可以在不创建两个未使用的列的情况下完成这项工作,但是似乎希望为联接使用索引。有没有办法让两个系列的值保持不变?有没有更快的numpy版本? 例如:

  • 问题内容: 我有一个大约20列的pandas数据框。 可以通过手动编写所有列名来替换所有出现的字符串(此处为换行符): 不幸的是,这不起作用: 还有其他更优雅的解决方案吗? 问题答案: 您可以使用并传递字符串以查找/替换为字典键/项目: 例如: