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

Python- pandas的行程是否有性能问题?

卢志强
2023-03-14
问题内容

我注意到使用pandas的迭代器时性能非常差。

这是别人所经历的吗?它特定于迭代吗?对于一定大小的数据(我正在处理2-3百万行),应该避免使用此功能吗?

在GitHub上进行的讨论使我相信,这是在数据帧中混合dtypes时引起的,但是下面的简单示例显示,即使使用一个dtype(float64)也存在该问题。这在我的机器上需要36秒:

import pandas as pd
import numpy as np
import time

s1 = np.random.randn(2000000)
s2 = np.random.randn(2000000)
dfa = pd.DataFrame({'s1': s1, 's2': s2})

start = time.time()
i=0
for rowindex, row in dfa.iterrows():
    i+=1
end = time.time()
print end - start

为什么矢量化运算之类的应用这么快?我想象那里也必须进行逐行迭代。

我无法弄清楚在我的情况下如何不使用迭代(这将在以后的问题中予以保留)。因此,如果你一直能够避免这种迭代,不胜感激。我正在基于单独数据框中的数据进行计算。谢谢!

—编辑:下面添加了我要运行的简化版本—

import pandas as pd
import numpy as np

#%% Create the original tables
t1 = {'letter':['a','b'],
      'number1':[50,-10]}

t2 = {'letter':['a','a','b','b'],
      'number2':[0.2,0.5,0.1,0.4]}

table1 = pd.DataFrame(t1)
table2 = pd.DataFrame(t2)

#%% Create the body of the new table
table3 = pd.DataFrame(np.nan, columns=['letter','number2'], index=[0])

#%% Iterate through filtering relevant data, optimizing, returning info
for row_index, row in table1.iterrows():   
    t2info = table2[table2.letter == row['letter']].reset_index()
    table3.ix[row_index,] = optimize(t2info,row['number1'])

#%% Define optimization
def optimize(t2info, t1info):
    calculation = []
    for index, r in t2info.iterrows():
        calculation.append(r['number2']*t1info)
    maxrow = calculation.index(max(calculation))
    return t2info.ix[maxrow]

问题答案:

通常,iterrows仅应在非常特殊的情况下使用。这是执行各种操作的一般优先顺序:

1) vectorization
2) using a custom cython routine
3) apply
    a) reductions that can be performed in cython
    b) iteration in python space
4) itertuples
5) iterrows
6) updating an empty frame (e.g. using loc one-row-at-a-time)

使用自定义的cython例程通常太复杂了,所以现在就跳过它。

1)矢量化始终是首选。但是,有一小部分案例无法以明显的方式进行向量化(主要涉及复发)。此外,在较小的框架上,执行其他方法可能会更快。

3)应用包括可通常是通过在用Cython空间迭代器(这在pandas内部完成的)来进行(这是一个)的情况下。

这取决于apply表达式内部发生的情况。例如,df.apply(lambda x: np.sum(x))将很快执行(当然df.sum(1)更好)。但是,类似:的操作df.apply(lambda x: x['b'] + 1)将在python空间中执行,因此速度较慢。

4)itertuples不会将数据装箱成一个系列,而只是将其作为元组返回

5)是否iterrows将数据包装到系列中。除非你真的需要此方法,否则请使用其他方法。

6)一次更新一个空行。我已经看到这种方法使用了太多的方法。这是迄今为止最慢的。它可能很常见(对于某些python结构来说相当快),但是DataFrame对索引进行了大量检查,因此每次更新一行总是很慢。创建新的结构和方法更好concat



 类似资料:
  • 我注意到使用来自Pandas的迭代行时性能非常差。 这是别人经历过的事情吗?它是特定于迭代行的吗?对于一定大小的数据(我正在处理200万-300万行),是否应该避免使用这个函数? GitHub上的讨论使我相信它是在数据帧中混合dtype时引起的,然而下面的简单示例显示,即使使用一个dtype(float64)时也会出现这种情况。这在我的计算机上需要36秒: 为什么像apply这样的矢量化操作要快得

  • 问题内容: 在我的一个类中,我有许多方法都从相同的字典中提取值。但是,如果其中一个方法尝试访问不存在的值,则它必须调用另一个方法以使该值与该键关联。 我目前已按以下方式实现此功能,其中findCrackDepth(tonnage)为self.lowCrackDepth [tonnage]分配一个值。 但是,我也有可能这样做 我假设两者之间存在性能差异,这与值在字典中的频率有关。这个差异有多大?我正

  • 问题内容: 我看到有一条禁止的附庸制度。 在规则的描述中,它声明了一个add 。 但是,当我查看[MDN 函数docs时,“简单示例”显示了一个示例,其中没有任何说明这可能是性能问题的原因。 如eslint文档所建议的那样,是否存在实际的性能问题? 如果是这样,怎么办? 问题答案: 不,没有任何性能 问题 。这只是不必要的额外操作。执行可能需要更长的时间,但几乎不会引起注意。它类似于而不是整数。或

  • 我看到有一条eslint规则,,用于禁止。 在规则的描述中,它声明一个添加。 但是,当我查看MDN函数文档时,“简单示例”显示了一个包含的示例,但没有说明这可能是性能问题的原因。 是否如eslint文档所建议的那样是一个实际的性能问题? 如果是,怎么做?

  • 问题内容: 我正在运行一个基本脚本,该脚本遍历嵌套字典,从每个记录中获取数据,并将其附加到Pandas DataFrame。数据看起来像这样: 总共有几百万条记录。脚本本身如下所示: 但是,这非常缓慢。在寻找并行化方法之前,我只是想确保我没有错过任何明显的东西,这些东西可以使它按原样更快地执行,因为我对Pandas还是很陌生。 问题答案: 我还在循环中使用了数据框的 append 函数,感到困惑的

  • 问题内容: 我的numpy数组用于指定缺少的值。在遍历数据集时,我需要检测这些缺失值并以特殊方式处理它们。 我天真地用过,除非不在所支持的类型子集中,否则它会很好地工作。例如,字符串字段中可能会出现丢失的数据,在这种情况下,我得到: 除了编写昂贵的包装来捕获异常并返回外,还有没有办法优雅而有效地处理此包装? 问题答案: (也是,在较新的版本中)检查数字数组和字符串/对象数组中的缺失值。从文档中,它