Python熊猫:。应用永远?

时间:2015-03-15 16:46:57

标签: python pandas dataframe machine-learning

我有一个DataFrame'点击'通过解析大小为1.4G的CSV创建。我试图创建一个新专栏' buy'使用应用功能。

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

在getBoughtItemIDs中,我正在检查是否购买' dataframe具有我想要的值,如果是,则返回连接它们的字符串。 getBoughtItemIDs的第一行是永远的。有什么方法可以让它更快?

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

1 个答案:

答案 0 :(得分:3)

有几件事使这段代码运行缓慢。

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

  • buys[buys['session'] == val].valuesval的每一行的整个列中查找clicks然后返回子DataFrame 和然后创建一个新的NumPy数组。以这种方式反复查找值很昂贵(每次查找O(n)复杂度)。创建新阵列将会非常昂贵,因为必须分配内存并且每次都要复制数据。

如果我了解您尝试做的事情,您可以尝试以下方法来获取新列。

首先使用groupby按{' session'中的值对buys行进行分组。 apply用于连接每个值的字符串:

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

其中col_to_joinbuys中的列,其中包含您要一起合并为字符串的值。

groupby表示只需要通过DataFrame传递一次,并且在Pandas中进行了非常优化。这里使用apply来加入字符串是不可避免的,但只需要通过分组值一次。

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

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

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