加快熊猫封锁

时间:2019-10-02 16:20:26

标签: python pandas

我可以使用一些帮助来加速此代码块。我假设concat ops是使代码变慢的原因,但是我不确定。这个循环执行我函数中其余代码的时间大约是20倍。

df = pd.DataFrame()
for index, row in p_data_df.iterrows():
    test_df = log_df.loc[row['Mid-C']].to_frame().transpose()
    if 'S' not in test_df.columns:
        test_df.insert(0, 'S', row.loc['S'])
        test_df.insert(1, 'C #', row.loc['C #'])
        test_df.insert(2, 'Num', row.loc['Num'])

    df = pd.concat([df, test_df], axis=0)

3 个答案:

答案 0 :(得分:2)

切勿在for循环内调用pd.concat。它导致二次复制:concat返回一个新的DataFrame。必须为新的DataFrame分配空间,并且必须将旧DataFrame中的数据复制到新的DataFrame中。

因此,如果您的数据帧具有N行,则完成循环需要O(N ^ 2)个副本。

使用字典列表或列表列表代替数据框来累积结果,并在for循环之外使用结果列表创建数据框。这样,您将节省大量执行时间,而熊猫并没有为此做。

这是您的方法:

list_res = []
for index, row in p_data_df.iterrows():
    test_df = log_df.loc[row['Mid-C']].to_frame().transpose()
    if 'S' not in test_df.columns:
        test_df.insert(0, 'S', row.loc['S'])
        test_df.insert(1, 'C #', row.loc['C #'])
        test_df.insert(2, 'Num', row.loc['Num'])
    list_res.append(test_df)

df = pd.concat(list_res, axis=0)

更多加快代码速度的提示

iterrows是用于迭代数据帧的最慢的方法,因为必须将每一行转换为一系列。如果您使用itertuples,则不会发生。您可以使用itertuples,而无需过多更改代码,但可以提高性能。

还有其他方法(矢量化,应用函数,Cython ...),它们需要对代码进行稍宽的修改,但可以使您拥有更高效的代码。我留下您this link,以获取更多信息。

答案 1 :(得分:1)

所使用的 <!-- Load Facebook SDK for JavaScript --> <div id="fb-root"></div> <script> window.fbAsyncInit = function() { FB.init({ xfbml : true, version : 'v4.0' }); }; (function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = 'https://connect.facebook.net/en_US/sdk/xfbml.customerchat.js'; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));</script> <!-- Your customer chat code --> <div class="fb-customerchat" attribution=setup_tool page_id="******" theme_color="#0084ff"> </div> 产生二次副本。每次添加一行时,此操作都会返回前一个数据帧的副本以及新行。更好的方法是保留所有行的列表,然后在最后只进行最后一个串联。

concat

答案 2 :(得分:1)

我能够想到这一点,它似乎至少快了一个数量级:

df = pd.concat([p_data_df.loc[:, ['S', 'C #', 'Num']], log_df[log_df['MD'].isin(p_data_df['Mid-C'].values)]], sort=False, axis=1)