pandas时间序列数据帧中的逻辑元素操作

时间:2017-04-14 06:13:17

标签: pandas numpy time-series logical-operators

我有一个带有时间戳日期时间索引的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
  6. 我尝试了多种解决方案,但似乎无法解决这个问题。如,

    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'

1 个答案:

答案 0 :(得分: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
  • 设置右侧断点ar
  • 设置右侧映射值br
  • searchsorted会在
  • 之前找到应放置值的索引
  • 使用searchsorted中的索引来标识映射值
  • 在查找右侧值时,我使用side='right'
  • 再次映射值。
  • 添加左右结果。 nan +值将为nan
  • ffill向前宣传价值。

<强> 设置
假设由OP

给出的数据帧df
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