【问题标题】:How to efficiently filter pandas dataframe如何有效过滤熊猫数据框
【发布时间】:2020-11-28 09:47:24
【问题描述】:

我有这个庞大的消费者交易数据集(1 亿行),如下所示:

df = pd.DataFrame({'id':[1, 1, 2, 2, 3],'brand':['a','b','a','a','c'], 'date': ['01-01-2020', '01-02-2020', '01-05-2019', '01-06-2019', '01-12-2018']})

对于每一行(每笔交易),我想检查是否同一个人(相同的“id”)过去为一个不同的品牌购买过东西。生成的数据集应如下所示:

    id  brand  date        check
0   1   a      01-01-2020  0  
1   1   b      01-02-2020  1
2   2   a      01-05-2019  0
3   2   a      01-06-2019  0
4   3   c      01-12-2018  0

现在,我的解决方案是:

def past_transaction(row):
    x = df[(df['id'] == row['id']) & (df['brand'] != row['brand']) & (df['date'] < row['date'])]
    if x.shape[0]>0:
        return 1
    else:
        return 0

df['check'] = df.appy(past_transaction, axis=1)

这很好用,但性能很差。有没有更有效的方法来做到这一点(有或没有熊猫)?谢谢!

【问题讨论】:

  • 首先,您使用apply 的核心功能将使性能比现在快100 倍。其次,pandas 不适用于大数据工作流。将其放入 SQL 数据库并在您的键列上添加索引或使用类似 sparkdask

标签: python pandas dataframe


【解决方案1】:

我个人会使用两个布尔值,

首先检查id是否重复。 其次是检查那些重复的id和品牌

import numpy as np 

s = df.duplicated(subset=['id'],keep='first')
s1 = ~df.duplicated(subset=['id','brand'],keep=False)
df['check'] = np.where(s & s1,1,0)


   id brand        date  check
0   1     a  01-01-2020      0
1   1     b  01-02-2020      1
2   2     a  01-05-2019      0
3   2     a  01-06-2019      0
4   3     c  01-12-2018      0

【讨论】:

    【解决方案2】:

    A) 使用 Pandas 内置函数

    第一步是利用 pandas 而不是自己制作函数:

    df['check'] = np.logical_and(df.id.duplicated(), ~df[['id','brand']].duplicated())
    

    它已经让你的代码变得更快了!

    B) 充分利用硬件

    如果您的 RAM 允许,您可以选择使用您机器中的所有内核。您可以使用modin.pandas 或任何替代方法。我推荐这个是因为它的变化很小,并且会根据你的机器配置提供指数级的加速

    C) 大数据框架

    如果是大数据问题,您应该已经在使用 daskspark 数据帧,它们旨在处理大数据,因为 pandas 并不意味着处理如此大量的数据。

    我在处理similar problem 时发现一些有效的方法。

    【讨论】:

    • 感谢您的建议。虽然代码会引发 Keyerror :(
    • 更新了!现在不应该!
    猜你喜欢
    • 2017-05-18
    • 1970-01-01
    • 2018-07-13
    • 2019-04-13
    • 2015-05-28
    • 2018-02-06
    • 2018-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多