2015-11-20 96 views
0

我是Python的新手,我努力編寫PHP/SQL中看起來很簡單的東西,我希望你能幫助我。Python函數使用來自另一個Dataframe的值在Pandas Dataframe中添加值

我有2個熊貓數據框,爲了更好的理解我已經簡化了。

在第一個數據幀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列中。

比方說預測是我創造,我要應用功能:

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創建於各行的循環來做到這一點在PHP和df2015檢索值(如果存在的話)由選擇WHERE商店= STORE_ID和日期=日期 .. ...但它似乎邏輯與Pandas Dataframes和Python不一樣。

我曾嘗試適用功能如下:

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

,但我無法正確地將這些參數或有件事我做錯了..

我以爲我不有沒有好的方法,或者也許我的方法不適合熊貓和Python ..?

回答

0

我相信你快到了!缺少的是函數,你已經傳入了參數。

apply函數接受函數及其參數。該文檔是here

沒有嘗試過這個我自己的系統上,我建議做:

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

我的道歉,我覺得'broadcast'說法是不必要的。我已經刪除它。 – ericmjl

0

一個關於熊貓的好處之一是,它處理缺少數據很好。訣竅是在兩個數據框上使用通用索引。舉例來說,無論dataframes的,如果我們設定的指標是「商店」欄目:

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 

SalesForecast店面2是NaN反映出店2不會在df2015數據幀存在。

0

請注意,如果你只需要1.05相乘從df2015 Sales列,你可以這樣做,都在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 

如果兩個DataFrames正好有兼容指數法已經,您可以在結果列直接簡單地寫df2016,即使是計算上的另一大taframe喜歡df2015。一般來說,你需要注意這一點,明確地執行連接可能更一般化(正如我通過使用merge函數所做的那樣)。哪種方式最好取決於您的應用程序和您對索引列的瞭解。

有關對列,整個數據幀或子幀組的更多一般功能應用,請參閱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'] 
) 
相關問題