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

将一系列int转换为字符串-为什么应用比astype快得多?

经伟
2023-03-14
问题内容

我有一个pandas.Series包含整数的整数,但对于某些下游工具,我需要将其转换为字符串。因此,假设我有一个Series对象:

import numpy as np
import pandas as pd

x = pd.Series(np.random.randint(0, 100, 1000000))

在StackOverflow和其他网站上,我已经看到大多数人认为做到这一点的最佳方法是:

%% timeit
x = x.astype(str)

这大约需要2秒钟。

当我使用时x = x.apply(str),只需0.2秒。

为什么x.astype(str)这么慢?推荐的方法应该是x.apply(str)吗?

我主要对此感兴趣的是python 3的行为。


问题答案:

性能

值得一开始,因为任何调查,与流行的观点之前看实际表现,list(map(str, x))似乎是 x.apply(str)

import pandas as pd, numpy as np

### Versions: Pandas 0.20.3, Numpy 1.13.1, Python 3.6.2 ###

x = pd.Series(np.random.randint(0, 100, 100000))

%timeit x.apply(str)          # 42ms   (1)
%timeit x.map(str)            # 42ms   (2)
%timeit x.astype(str)         # 559ms  (3)
%timeit [str(i) for i in x]   # 566ms  (4)
%timeit list(map(str, x))     # 536ms  (5)
%timeit x.values.astype(str)  # 25ms   (6)

值得注意的一点:

  1. (5)比(3)/(4)快一点,随着更多的工作移到C中[我们假设不lambda使用任何功能] ,我们期望。
  2. (6)是迄今为止最快的。
  3. (1)/(2)相似。
  4. (3)/(4)相似。

为什么x.map / x.apply快速?

似乎是 因为它使用了快速编译的Cython代码:

cpdef ndarray[object] astype_str(ndarray arr):
    cdef:
        Py_ssize_t i, n = arr.size
        ndarray[object] result = np.empty(n, dtype=object)

    for i in range(n):
        # we can use the unsafe version because we know `result` is mutable
        # since it was created from `np.empty`
        util.set_value_at_unsafe(result, i, str(arr[i]))

    return result

为什么x.astype(str)慢?

熊猫适用str于该系列中的每个项目,而不使用上述Cython。

因此,性能可与[str(i) for i in x]/相媲美list(map(str, x))

为什么x.values.astype(str)这么快?

Numpy不会在数组的每个元素上应用函数。我发现了对此的一种描述:

如果您做s.values.astype(str)了,您将得到一个持有的对象
int。这是numpy在进行转换,而熊猫会遍历每个项目并调用str(item)它。因此,如果您s.astype(str)拥有对象持有权str

有一个技术原因,在没有空值的情况下,尚未实现numpy版本。



 类似资料:
  • 我只是无法在c中转换不同的数据类型,我知道c是一种强类型语言,所以我在这里使用了,但我面临一个问题,错误消息是 从“std::string{aka std::basic_string}类型转换为“int”类型的static_

  • 问题内容: Oracle Java Community网站上的一篇文章提供了以下方法作为示例(对于JPA Converter,但这并不相关): 将String y强制转换为String val有什么用?有正当的理由吗? 原始文章:JPA的新增功能 问题答案: 这样的转换是完全没有必要的。我可以想象那是以前 但是后来参数类型更改为,而作者只是忘了删除强制类型转换。

  • 注意:这个问题包含不建议使用的前1.0代码!不过,答案是正确的。 要在Rust中将转换为,我可以执行以下操作: 我知道如何将转换为的唯一方法是获取其中的一个片段,然后像这样使用: 有没有办法直接将转换为?

  • 问题内容: 基本上,我有一个单线将其转换为字符串“ 1、2、3”(我需要定界符是自定义的,有时是,有时是等)。以下是我能想到的最好的方法。在线搜索,似乎找不到更好的答案。 在大多数语言中,对此都有内置的支持,例如: 蟒蛇: 走: 当然,肯定有一个实用工具可以让我用单线执行此操作吗? 我知道有,但是仅当A已经[]字符串时才有效。 问题答案: 转换 到一行分隔字符串,例如 “ 1,2,3,4,5,6,

  • 问题内容: 我在系列中有一个类别变量。我想为每个唯一值分配整数ID,并使用ID创建一个新的系列,从而有效地将字符串变量转换为整数变量。最紧凑/最有效的方法是什么? 问题答案: 您可以使用pandas.factorize:

  • 问题内容: 该应用程序基本上通过输入初始速度和最终速度以及时间来计算加速度,然后使用公式来计算加速度。但是,由于文本框中的值是字符串,所以我无法将它们转换为整数。 问题答案: 基本概念, 请注意,这仅在Swift 1.x中有效 Swift 4更新