2017-04-14 79 views
1

我有一個帶有時間戳日期時間索引和對應於每個日期的值的pandas DataFrame。例如,df = pd.DataFrame(['0.11', '0.07', '0.04', '-0.11', '-0.04', '0.08', '0.1'], index=['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04', '2017-01-05', '2017-01-06', '2017-01-07'], columns=['values'])熊貓時間序列數據框中的邏輯元素操作

我想創建一個額外的列(我們稱之爲'new_value')基於上述數據框的當前和歷史值。

邏輯應該是:

  1. 如果一個值大於或等於0.1, 'NEW_VALUE' 應設置 爲-1,
  2. 一次 'NEW_VALUE' 被設置爲-1,它應保持-1直到一個值 小於或等於0.05被登記時,
  3. 如果一個值小於或等於-0.1,「NEW_VALUE」應設置 到1,
  4. 一次「NEW_VALUE '設置爲+1,它應該保持+1直到一個值 大於或等於-0.05註冊,
  5. 否則「NEW_VALUE」等於0

我曾嘗試多種解決方案,但似乎無法來解決這個問題。例如,

new_frame = pd.DataFrame(np.zeros(len(df.index),index=df.index,columns=['new_value']) 
for date in df.index: 
    if df['value'][date.strftime('%Y-%m-%d')] > 0.1: 
     new_frame.set_value(date.strftime("%Y-%m-%d"),'new_value',-1) 

但我收到的錯誤:'ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().'

如果我再更改第三行:

if df['value'][date.strftime('%Y-%m-%d').item() > 0.1: 

我收到的錯誤:'ValueError: can only convert an array of size 1 to a Python scalar'

回答

2

numpy.searchsorted

s = df['values'].astype(float) 
al = np.array([-.1, -.05]) 
bl = np.array([1, np.nan, 0]) 
ar = np.array([.05, .1]) 
br = np.array([0, np.nan, -1]) 
l = bl[al.searchsorted(s.values)] 
r = br[ar.searchsorted(s.values, side='right')] 

df.assign(new_values=pd.Series(l + r, s.index).ffill()) 

      values new_values 
2017-01-01 0.11  -1.0 
2017-01-02 0.07  -1.0 
2017-01-03 0.04   0.0 
2017-01-04 -0.11   1.0 
2017-01-05 -0.04   0.0 
2017-01-06 0.08   0.0 
2017-01-07 0.1  -1.0 

它是如何工作

  • 需要得到的只是一系列的花車,將其命名爲s
  • 設立左側斷點al
  • 設立左側映射值bl
  • 集up right side breakpoints ar
  • 設置右側映射值br
  • searchsorted會發現,價值應該放在前
  • 使用指數從searchsorted尋找右側值時標識映射值
  • 指數,我再次使用side='right'
  • 映射值。
  • 添加左右結果。 nan +的值將是nan
  • ffill向前傳播值。

設置
假設由OP

df = pd.DataFrame(
    ['0.11', '0.07', '0.04', '-0.11', 
    '-0.04', '0.08', '0.1'], 
    ['2017-01-01', '2017-01-02', 
    '2017-01-03', '2017-01-04', 
    '2017-01-05', '2017-01-06', 
    '2017-01-07'], 
    ['values'] 
) 

      values 
2017-01-01 0.11 
2017-01-02 0.07 
2017-01-03 0.04 
2017-01-04 -0.11 
2017-01-05 -0.04 
2017-01-06 0.08 
2017-01-07 0.1 
+0

這是一個偉大的答案給定的數據幀df,謝謝。在建立我的理解方面,是否有人能夠解釋爲什麼我原來的方法不起作用? –

+1

@Panda_User看到[***這個答案***](http://stackoverflow.com/a/43222675/2336654)隨時投票,如果它的幫助:-) – piRSquared

+0

@Panda_User我看到你卡住了在最初階段...是的,我給你的是一個矢量化的解決方案。你正在使用循環的道路。現在你不需要。許多人在執行循環時陷入了將系列評估爲布爾值的陷阱。 – piRSquared