【问题标题】:Python function to add values in a Pandas Dataframe using values from another DataframePython 函数使用来自另一个 Dataframe 的值在 Pandas Dataframe 中添加值
【发布时间】:2015-11-20 19:00:12
【问题描述】:

我是 Python 的新手,我正在努力编写 PHP/SQL 中看似简单的东西,希望您能帮助我。

我有 2 个 Pandas 数据框,我已对其进行了简化以便更好地理解。

在第一个数据框 df2015 中,我有 2015 年的销售额。 !请注意,不幸的是,我们没有每个商店的所有值!

>>> df2015

    Store   Date        Sales       
0   1       2015-01-15  6553        
1   3       2015-01-15  7016        
2   6       2015-01-15  8840    
3   8       2015-01-15  10441
4   9       2015-01-15  7952

另一个名为 df2016 的数据框用于 2016 年的销售预测,其中列出了 ALL 商店。
(如您所料,列 SalesForecast 是要填充的列。)

>>> df2016

    Store   Date        SalesForecast
0   1       2016-01-15      
1   2       2016-01-15  
2   3       2016-01-15  
3   4       2016-01-15  
4   5       2016-01-15  

我想创建一个函数,为 df2016 中的每一行检索 df2015 中的销售额值,例如,将这些值增加 5% 并添加df2016 的 SalesForecast 列中的这些新值。

假设 forecast 是我创建的要应用的函数:

def forecast(store_id,date):
    sales2015 = df2015['Sales'].loc[(df2015['Store'].values == store_id) & (df2015['Date'].values == date )].values
    forecast2016 = sales2015 * 1.05
    return forecast2016

我已经用下面的硬编码方式测试了这个函数,它可以工作:

>>> forecast(1,'2015-01-15')
array([ 6880.65])

但这里是我的问题所在...如何将此函数应用于数据帧?

通过为 df2016 中的每一行创建一个循环并通过 SELECT 从 df2015 检索值(如果存在),在 PHP 中很容易做到这一点和 WHERE Store = store_id 和 Date = date.. ...但看起来逻辑与 Pandas Dataframes 和 Python 不一样。

我已经尝试了 apply 功能如下:

df2016['SalesForecast'] = df2016.apply(df2016['Store'],df2016['Date'])

但我无法正确提出论点,或者我做错了什么..

我认为我没有好的方法,或者我的方法可能根本不适合 Pandas 和 Python..?

【问题讨论】:

    标签: python function python-2.7 pandas apply


    【解决方案1】:

    我相信你快到了!缺少的是函数,你已经传入了参数。

    apply 函数接受一个函数及其参数。文档是here。

    如果没有在我自己的系统上尝试过,我建议这样做:

    df2016['SalesForecast'] = df2016.apply(func=forecast, args=(df2016['Store'],df2016['Date']))
    

    【讨论】:

    • 我很抱歉,我认为 broadcast 参数是不必要的。我已经删除了。
    【解决方案2】:

    Pandas 的优点之一是它可以很好地处理丢失的数据。诀窍是在两个数据帧上使用公共索引。例如,如果我们将两个数据框的索引都设置为“Store”列:

    df2015.set_index('Store', inplace=True)
    df2016.set_index('Store', inplace=True)
    

    那么做你想做的事就这么简单:

    df2016['SalesForecast'] = df2015['Sales'] * 1.05
    

    导致:

                 Date  SalesForecast
    Store                           
    1      2016-01-15        6880.65
    2      2016-01-15            NaN
    3      2016-01-15        7366.80
    4      2016-01-15            NaN
    5      2016-01-15            NaN
    

    商店 2 的 SalesForecast 是 NaN 反映了 df2015 数据帧中不存在商店 2 的事实。

    【讨论】:

      【解决方案3】:

      请注意,如果您只需要将 df2015 中的 Sales 列乘以 1.05,您就可以这样做,全部在 df2015 中:

      In [18]: df2015['Forecast'] = df2015['Sales'] * 1.05
      
      In [19]: df2015
      Out[19]: 
         Store        Date  Sales  Forecast
      0      1  2015-01-15   6553   6880.65
      1      3  2015-01-15   7016   7366.80
      2      6  2015-01-15   8840   9282.00
      3      8  2015-01-15  10441  10963.05
      4      9  2015-01-15   7952   8349.60
      

      此时,如果您需要该结果出现在df2016 数据集中,您可以将该结果加入df2016:

      In [20]: pandas.merge(df2016,      # left side of join
                            df2015,      # right side of join
                            on='Store',  # similar to SQL 'on' for 'join'
                            how='outer', # same as SQL, outer join.
                            suffixes=('_2016', '_2015')) # rename same-named
                                                         # columns w/suffix
      Out[20]: 
         Store   Date_2016   Date_2015  Sales  Forecast
      0      1  2016-01-15  2015-01-15   6553   6880.65
      1      2  2016-01-15         NaN    NaN       NaN
      2      3  2016-01-15  2015-01-15   7016   7366.80
      3      4  2016-01-15         NaN    NaN       NaN
      4      5  2016-01-15         NaN    NaN       NaN
      5      6  2016-01-15  2015-01-15   8840   9282.00
      6      7  2016-01-15         NaN    NaN       NaN
      7      8  2016-01-15  2015-01-15  10441  10963.05
      8      9  2016-01-15  2015-01-15   7952   8349.60
      

      如果两个 DataFrame 碰巧已经有兼容的索引,您可以直接在结果列中写入 df2016,即使它是在另一个 DataFrame 上的计算,例如 df2015。不过一般来说,您需要注意这一点,明确地执行连接可能更通用(就像我在上面使用 merge 函数所做的那样)。哪种方式最好取决于您的应用程序和您对索引列的了解。

      对于列、整个 DataFrame 或子帧组的更一般的函数应用,请参阅the documentation for this type of operation in Pandas。

      还有一些食谱示例的链接,并与您可能用 SQL 表达类似操作的方式进行比较。

      请注意,我创建了数据以使用以下命令复制您的示例数据:

      df2015 = pandas.DataFrame([[1, datetime.date(2015, 1, 15), 6553], 
                                 [3, datetime.date(2015, 1, 15), 7016], 
                                 [6, datetime.date(2015, 1, 15), 8840], 
                                 [8, datetime.date(2015, 1, 15), 10441], 
                                 [9, datetime.date(2015, 1, 15), 7952]],
                                columns=['Store', 'Date', 'Sales'])
      
      from itertools import izip_longest
      df2016 = pandas.DataFrame(
          list(izip_longest(range(1,10), 
                            [datetime.date(2016, 1, 15)], 
                            fillvalue=datetime.date(2016, 1, 15))), 
          columns=['Store', 'Date']
      )
      

      【讨论】:

        猜你喜欢
        • 2019-03-10
        • 2021-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-15
        • 2021-11-23
        • 1970-01-01
        • 2021-09-28
        相关资源
        最近更新 更多