【问题标题】:How to iterate over a Pandas DataFrame based on some condition to create a new DateFrame如何根据某些条件迭代 Pandas DataFrame 以创建新的 DateFrame
【发布时间】:2020-08-13 01:10:26
【问题描述】:

我已将 csv 文件导入到 Pandas DataFrame 中,其中包含销售管道数据。每条线代表一个机会,包括潜在客户名称、产品信息、管道阶段、概率、预期交易规模、预期结束日期、持续时间等。

现在我想将其转换为销售预测,我想通过将交易规模除以持续时间乘以概率来计算每个时期的平均收入。然后根据预期的结束日期和持续时间为所有可能的期间创建一条线。

我创建了一个简化示例来支持我的问题:

import pandas as pd

pipeline_data = [{'Client': 'A', 'Stage': 'suspect', 'Probability': '0.25', 'Dealsize': '1200', 'Duration': 6, 'Start_period': '2020-08'}, {'Client': 'B', 'Stage': 'prospect', 'Probability': '0.60', 'Dealsize': '1000', 'Duration': 4, 'Start_period': '2020-10'}]

df = pd.DataFrame(pipeline_data)
df

输出:

    Client  Stage    Probability Dealsize   Duration    Start_period
0   A       suspect  0.25        1200       6           2020-08
1   B       prospect 0.60        1000       4           2020-10

因此,客户每月的平均收入为 1200 / 6 * 0.25 = 50。收入将在 2020 年 8 月至 2021 年 1 月期间下降(即从 2020 年 8 月到 2021 年 1 月)。

首选输出是:

    Client  Stage    Probability Dealsize   Duration    Start_period Weighted_revenue Period
0   A       suspect  0.25        1200       6           2020-08      50               2020-08
1   A       suspect  0.25        1200       6           2020-08      50               2020-09
2   A       suspect  0.25        1200       6           2020-08      50               2020-10 
3   A       suspect  0.25        1200       6           2020-08      50               2020-11
4   A       suspect  0.25        1200       6           2020-08      50               2020-12
5   A       suspect  0.25        1200       6           2020-08      50               2021-01
6   B       prospect 0.60        1000       4           2020-10      150              2020-10
7   B       prospect 0.60        1000       4           2020-10      150              2020-11
8   B       prospect 0.60        1000       4           2020-10      150              2020-12
9   B       prospect 0.60        1000       4           2020-10      150              2021-01

我已经将 Start_period 转换为 Period 类型,因此它可以用于计算/迭代。

我对编码很陌生。我试图在这个网站和其他网站上找到答案,但到目前为止还没有成功。我可以想象使用某种嵌套循环和附加函数来解决这个问题,但我不知道如何将它与 Pandas 一起使用......

任何帮助将不胜感激!

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    您可以尝试使用列表理解,pd.date_rangeexplode

    df['Weighted_revenue']=(df['Dealsize'].astype(float)/df['Duration'].astype(float))*df['Probability'].astype(float)
    df['Period']=[pd.date_range(x, periods=y, freq="M").strftime('%Y-%m') for x,y in zip(df["Start_period"], df["Duration"])]
    df=df.explode('Period')
    

    输出:

    df
      Client     Stage Probability Dealsize  Duration Start_period  Weighted_revenue   Period
    0      A   suspect        0.25     1200         6      2020-08              50.0  2020-08
    0      A   suspect        0.25     1200         6      2020-08              50.0  2020-09
    0      A   suspect        0.25     1200         6      2020-08              50.0  2020-10
    0      A   suspect        0.25     1200         6      2020-08              50.0  2020-11
    0      A   suspect        0.25     1200         6      2020-08              50.0  2020-12
    0      A   suspect        0.25     1200         6      2020-08              50.0  2021-01
    1      B  prospect        0.60     1000         4      2020-10             150.0  2020-10
    1      B  prospect        0.60     1000         4      2020-10             150.0  2020-11
    1      B  prospect        0.60     1000         4      2020-10             150.0  2020-12
    1      B  prospect        0.60     1000         4      2020-10             150.0  2021-01
    

    详情:

    首先,我们使用您描述的公式创建'Weighted_revenue' 列:

    df['Weighted_revenue']=(df['Dealsize'].astype(float)/df['Duration'].astype(float))*df['Probability'].astype(float)
    df
    
      Client     Stage Probability Dealsize  Duration Start_period  Weighted_revenue
    0      A   suspect        0.25     1200         6      2020-08              50.0
    1      B  prospect        0.60     1000         4      2020-10             150.0
    

    然后,我们使用zip 的列表推导根据'Start_period''Duration' 列创建日期范围

    df['Period']=[pd.date_range(x, periods=y, freq="M").strftime('%Y-%m') for x,y in zip(df["Start_period"], df["Duration"])]
    df
    
      Client     Stage Probability Dealsize  Duration Start_period  Weighted_revenue                                             Period
    0      A   suspect        0.25     1200         6      2020-08              50.0  [2020-08, 2020-09, 2020-10, 2020-11, 2020-12, 2021-01]
    1      B  prospect        0.60     1000         4      2020-10             150.0               [2020-10, 2020-11, 2020-12, 2021-01]
    

    最后我们使用explode 来扩展列表:

    df=df.explode('Period')
    df 
    
     Client     Stage Probability Dealsize  Duration Start_period  Weighted_revenue   Period
    0      A   suspect        0.25     1200         6      2020-08              50.0  2020-08
    0      A   suspect        0.25     1200         6      2020-08              50.0  2020-09
    0      A   suspect        0.25     1200         6      2020-08              50.0  2020-10
    0      A   suspect        0.25     1200         6      2020-08              50.0  2020-11
    0      A   suspect        0.25     1200         6      2020-08              50.0  2020-12
    0      A   suspect        0.25     1200         6      2020-08              50.0  2021-01
    1      B  prospect        0.60     1000         4      2020-10             150.0  2020-10
    1      B  prospect        0.60     1000         4      2020-10             150.0  2020-11
    1      B  prospect        0.60     1000         4      2020-10             150.0  2020-12
    1      B  prospect        0.60     1000         4      2020-10             150.0  2021-01
    

    【讨论】:

    • 列表解析可能会表现更好:df['Period'] = [pd.date_range(x, periods=y, freq="M").strftime('%Y-%m') for x,y in zip(df["Start_period"], df["Duration"])].
    • @HenryYik - 这是真的,因为创作只会考虑那两列,只是根据您的建议编辑了答案,谢谢!
    • 感谢大家的快速响应,非常感谢!这么多我从未听说过的新代码……要学的东西太多了。我会试一试,然后回到“接受”
    • 通过一些细微的调整,它在我的实际代码上表现出色。再次感谢。
    • 会这样做!干杯
    猜你喜欢
    • 2020-04-25
    • 1970-01-01
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多