【问题标题】:Python Pandas: .apply taking forever?Python Pandas:.apply 需要永远吗?
【发布时间】:2015-05-17 18:30:32
【问题描述】:

我有一个通过解析大小为 1.4G 的 CSV 创建的 DataFrame 'clicks'。我正在尝试使用 apply 函数创建一个“购买”的新列。

clicks['bought'] = clicks['session'].apply(getBoughtItemIDs)

在 getBoughtItemIDs 中,我正在检查 'buys' 数据框是否有我想要的值,如果有,则返回一个连接它们的字符串。 getBoughtItemIDs 中的第一行将永远占用。有什么方法可以加快速度?

def getBoughtItemIDs(val):
  boughtSessions = buys[buys['session'] == val].values
  output = ''
  for row in boughtSessions:
    output += str(row[1]) + ","
  return output

【问题讨论】:

    标签: python pandas dataframe machine-learning


    【解决方案1】:

    有几件事会导致此代码运行缓慢。

    • apply 本质上只是for 在列的行上循环的语法糖。在你的函数中还有一个显式的 for 循环遍历 NumPy 数组(for row in boughtSessions 部分)。最好尽可能避免以这种(非矢量化)方式循环,因为它会严重影响性能。

    • buys[buys['session'] == val].values 正在为clicks 的每一行在整个列中查找val然后返回一个子数据帧然后创建一个新的 NumPy 数组。以这种方式重复查找值是昂贵的(O(n) 每次查找的复杂性)。创建新数组会很昂贵,因为每次都必须分配内存并复制数据。

    如果我理解您想要做什么,您可以尝试以下方法来获取您的新专栏。

    首先使用groupbybuys 的行按“会话”中的值分组。 apply 用于连接每个值的字符串:

    boughtSessions = buys.groupby('session')[col_to_join].apply(lambda x: ','.join(x))
    

    其中col_to_join 是来自buys 的列,其中包含您要连接到一个字符串中的值。

    groupby 意味着只需要一次通过 DataFrame,并且在 Pandas 中得到了很好的优化。此处使用apply 连接字符串是不可避免的,但只需要通过分组值。

    boughtSessions 现在是由“会话”列中的唯一值索引的一系列字符串。这很有用,因为查找 Pandas 索引的复杂度是 O(1)

    要将boughtSessions 中的每个字符串与clicks['session'] 中的方法值匹配,您可以使用map。与apply 不同,map 是完全矢量化的,应该非常快:

    clicks['bought'] = clicks['session'].map(boughtSessions)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-08
      • 2014-11-07
      • 2021-03-17
      • 2014-02-24
      • 2014-07-08
      • 2013-02-17
      • 1970-01-01
      相关资源
      最近更新 更多