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

Python-为什么DataFrames的串联速度变慢?

酆晔
2023-03-14
问题内容

我有一个处理DataFrame的函数,主要用于将数据处理到存储桶中,使用会在特定列中创建功能的二进制矩阵pd.get_dummies(df[col])

为了避免立即使用此函数处理所有数据(该数据将耗尽内存并导致iPython崩溃),我使用以下方法将大型DataFrame分为多个块:

chunks = (len(df) / 10000) + 1
df_list = np.array_split(df, chunks)

pd.get_dummies(df)会自动创建一个基于内容的新栏目df[col]和这些都有可能为每个不同df在df_list。

加工后,我串接DataFrames回到一起使用:

for i, df_chunk in enumerate(df_list):
    print "chunk", i
    [x, y] = preprocess_data(df_chunk)
    super_x = pd.concat([super_x, x], axis=0)
    super_y = pd.concat([super_y, y], axis=0)
    print datetime.datetime.utcnow()

第一块的处理时间是完全可以接受的,但是,每个块会增加!这与无关,preprocess_data(df_chunk)因为没有理由增加它。通话是否会增加时间pd.concat()

请查看以下日志:

chunks 6
chunk 0
2016-04-08 00:22:17.728849
chunk 1
2016-04-08 00:22:42.387693 
chunk 2
2016-04-08 00:23:43.124381
chunk 3
2016-04-08 00:25:30.249369
chunk 4
2016-04-08 00:28:11.922305
chunk 5
2016-04-08 00:32:00.357365

有没有解决方法可以加快速度?我有2900个区块需要处理,因此我们将不胜感激!

欢迎使用Python中的其他建议!


问题答案:

不要调用DataFrame.appendpd.concat一个for循环中。这导致二次复制。

pd.concat返回一个新的DataFrame。必须为新的DataFrame分配空间,并且必须将旧DataFrame中的数据复制到新的DataFrame中。考虑以下行中所需的复制数量for-loop(假设每个副本的x大小为1):

super_x = pd.concat([super_x, x], axis=0)

| iteration | size of old super_x | size of x | copying required |
|         0 |                   0 |         1 |                1 |
|         1 |                   1 |         1 |                2 |
|         2 |                   2 |         1 |                3 |
|       ... |                     |           |                  |
|       N-1 |                 N-1 |         1 |                N |

1 + 2 + 3 + ... + N = N(N+1)/2。因此,O(N**2)需要一些副本才能完成循环。

现在考虑

super_x = []
for i, df_chunk in enumerate(df_list):
    [x, y] = preprocess_data(df_chunk)
    super_x.append(x)
super_x = pd.concat(super_x, axis=0)

追加到列表是一项O(1)操作,不需要复制。pd.concat循环完成后,现在只有一个调用。pd.concat由于super_x包含N 大小为1的DataFrame,因此对N的调用 需要进行N个拷贝。因此,以这种方式构造时,super_x需要O(N) 拷贝。



 类似资料:
  • 令人惊讶的是,我发现比中的 操作中的 和< code>__contains__之间添加测试结果:

  • 因此,当增加randint()中的界限时,排序列表上的循环会变慢。为什么?

  • 问题内容: 今天,我做了一些快速基准测试来测试and的速度性能: 结果如下: 为什么运行速度差异如此之大? 基准系统: 问题答案: 从这个Oracle博客中: 使用GetSystemTimeAsFileTime方法实现该方法,该方法本质上只是读取Windows维护的低分辨率日期时间值。读取此全局变量自然非常快- 根据报告的信息,大约需要6个周期。 使用 (如果可用,则返回。)实现,具体取决于运行的

  • 问题内容: 我有一个名为Memcached.Js的项目,它是Memcached服务器到Node.js的端口。 我一直在使用字符串和缓冲区进行比较,比较内存占用量和性能。对于内存,毫无疑问,缓冲区是正确的选择。 但令我惊讶的是,表演并非如此。执行字符串操作比使用缓冲区更快。这是我尝试的: 完整的代码在这里:https : //github.com/dalssoft/memcached.js/blob

  • 问题内容: 在SQL Server(2008)中,我在两列上都有一个FullText索引,将它们称为和。对一些查询进行概要分析后,我得出了以下结果: => 31197毫秒 => 1941毫秒 => 3201毫秒 => 565毫秒 => 670毫秒 => 17毫秒 => 3毫秒 即使我重建FullText索引,此行为仍然存在。 与对特定语言的大量数据进行LIKE查询相比,FullText通常要快得多

  • 问题内容: C ++ 运行: 时间: 蟒蛇 运行: 时间: 谁能解释两个程序所花费的时间之间的巨大差异?怎样才能加快python的速度呢? 问题答案: 这是区别的一个简单示例: 在C 中,C 可以编译成简单的指令(在x86-64机器上)。只需执行一小部分周期即可执行。 可以使用模块中的Python进行反汇编,通过该模块可以通知我们所涉及的字节码为: 在线尝试! 从技术上讲,所有的指令,在最终成为一