【问题标题】:Pandas find sequence or pattern in columnPandas 在列中查找序列或模式
【发布时间】:2020-07-02 07:01:27
【问题描述】:

以下是我正在处理的问题的一些示例数据:

index     Quarter    Sales_Growth
0          2001q1    0
1          2002q2    0
2          2002q3    1
3          2002q4    0
4          2003q1    0
5          2004q2    0
6          2004q3    1
7          2004q4    1

Sales_Growth 列告诉我该季度是否确实有销售增长。 0 = 没有增长,1 = 增长。

首先,当连续两个季度没有销售增长时,我试图返回第一个 Quarter

有了上面的数据,这个答案就是2001q1

然后,我想返回在最初两个季度没有增长之后发生的第二个季度连续销售增长。

这个问题的答案是2004q4

我已经搜索过,但我找不到最接近的答案:https://stackoverflow.com/a/26539166/3225420

我是 Pandas 初学者。

【问题讨论】:

    标签: python pandas dataframe sequence


    【解决方案1】:

    您正在进行子序列匹配。这有点奇怪,但请耐心等待:

    growth = df.Sales_Growth.astype(str).str.cat()
    

    这给了你:

    '00100011'
    

    然后:

    growth.index('0011')
    

    给你 4(显然你会添加一个常量 3 来获得模式匹配的最后一行的索引)。

    我觉得这种方法一开始有点难看,但最终的结果真的很好用——你可以搜索任何固定的模式,而不需要额外的编码。

    【讨论】:

    • 选择这个答案有两个主要原因:首先,它有效,其次我理解它。其他答案可能同样有效,但超出了我的理解。错不在于提供我不理解的人,而在于我。我需要了解更多。简单分享我的推理。
    • @SDS:干杯。我还发现这种处理方式更容易思考。此外,它的打字更少。 :)
    • 只是……太棒了! :)
    【解决方案2】:

    对于第一季度:

    temp = df.Sales_Growth + df.Sales_Growth.shift(-1)
    df[temp == 0].head(1)
    

    第二季度:

    df[(df.Sales_Growth == 1) & (df.Sales_Growth.shift(1) == 1) & (df.Sales_Growth.shift(2) == 0) & (df.Sales_Growth.shift(3) == 0)].head(1)
    

    【讨论】:

    • 这应该是最佳答案。 @john-zwink 上面的答案并没有推广到多列,需要您手动序列化/分隔数据,并且会在搜索之前在内存中生成整个字符串。转移到正确的解决方案!
    【解决方案3】:

    以较早的答案为基础。 Q1:

    temp = df.Sales_Growth.rolling_apply(window=2, min_periods=2, \
        kwargs={pattern: [0,0]}, func=lambda x, pattern: x == pattern)
    print(df[temp==1].head())
    

    在 rolling_apply 调用中,windowmin_periods 必须与传递给 rolling_apply 函数的模式列表的长度相匹配。

    Q2:相同的方法,不同的模式:

    temp = df.Sales_Growth.rolling_apply(window=4, min_periods=4, \
        kwargs={pattern: [0,0,1,1]}, func=lambda x, pattern: x == pattern)
    print(df[temp==1].head())
    

    【讨论】:

    • 你在这里有效地制作了一个 Python 循环,这很慢。通常在 Pandas 中我们会避免这种情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-20
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2018-07-20
    相关资源
    最近更新 更多