【问题标题】:Create dataframe column using np.where or similar when criteria matches当条件匹配时,使用 np.where 或类似方法创建数据框列
【发布时间】:2016-07-10 22:39:49
【问题描述】:

当某些条件匹配时,我尝试使用 np.where 或类似方法创建数据框列,如下所示:

这个链接的pickle file 是我正在使用的数据的一部分。这是我目前使用的代码:

data = pd.read_pickle('data_df')

data

    Open    High    Low Last    Volume
Timestamp                   
2014-03-04 09:30:00 1783.50 1784.50 1783.50 1784.50 171
2014-03-04 09:31:00 1784.75 1785.75 1784.50 1785.25 28
2014-03-04 09:32:00 1785.00 1786.50 1785.00 1786.50 81
2014-03-04 09:33:00 1786.00 1786.00 1785.25 1785.25 41
2014-03-04 09:34:00 1785.00 1785.25 1784.75 1785.25 11

这些是我需要在 np.where 元素中使用的时间变量:

#Times
daystart = '9:30'
dayend = '16:14:59'
IB_end = '10:29:59'

IB_session = data.between_time(daystart,IB_end, include_start=True, include_end=True)
day_session = data.between_time(daystart,dayend, include_start=True, include_end=True)

这些是这些时间段的最高点和最低点:

IB_high = IB_session['High'].rolling(window=1,freq='D').max()
IB_low = IB_session['Low'].rolling(window=1,freq='D').min()

我需要编写一个 np.where 语句或类似的语句来创建新的列显示:

data['Last'] > IB_highdata['Last'] < IB_low 时,我的声明需要确保每天只发生其中一种情况。需要在“IB_High_Break”或“IB_Low_Break”列中使用简单的 1 来标记这种情况。这最终将用作进入交易的信号。

我试过用这个:

data['IB_High_Break'] = np.where(data['Last'] > IB_high,1, np.nan);
data['IB_Low_Break'] = np.where(data['Last'] < IB_low,1,np.nan);

但是得到一个错误ValueError: Series lengths must match to compare

任何人都可以帮忙并展示一个好的方法吗?

【问题讨论】:

  • 如果提供准确答案过于耗时,我们将不胜感激任何其他帮助。谢谢
  • 我试图包含原始数据,但它是否让人们不必打开 pickle 文件?我应该使用随机生成的测试数据再次提问吗?

标签: python pandas


【解决方案1】:

如果您遇到长度问题并且可以将数据放入同一个数组中,请在此处执行以下操作:...

>>> a = pd.Series(np.arange(10))
>>> b = pd.Series(np.arange(100,111))
>>> df = pd.DataFrame([a,b])
>>> df = df.T
>>> df.loc[4.5]=nan
>>> df.sort_index(inplace=True)
>>> df.interpolate(inplace=True)
>>> df
        0      1
0.0   0.0  100.0
1.0   1.0  101.0
2.0   2.0  102.0
3.0   3.0  103.0
4.0   4.0  104.0
4.5   4.5  104.5
5.0   5.0  105.0
6.0   6.0  106.0
7.0   7.0  107.0
8.0   8.0  108.0
9.0   9.0  109.0
10.0  9.0  110.0
>>> df.loc[4.5,1]=0
>>> np.where(df[0]<df[1],1,np.nan)
array([  1.,   1.,   1.,   1.,   1.,  nan,   1.,   1.,   1.,   1.,   1.,
         1.])
>>> np.where(df[0]>df[1],1,np.nan)
array([ nan,  nan,  nan,  nan,  nan,   1.,  nan,  nan,  nan,  nan,  nan,
        nan])
>>>

否则你需要做一些迭代......

【讨论】:

    【解决方案2】:

    我想我曾经听说过不应该在未知/不受信任的实体之间共享腌制文件,因为它不是为了安全反序列化而构建的,所以这个答案只是基于略读你的代码。

    我认为你得到了不等长的 pandas.Series,因为你的布尔创建了一个新的 pandas Series,其长度等于满足你的布尔值的行,因此 data['Last'] &gt; IB_highdata['Last'] &lt; IB_high 不可能有相同的长度作为数据数据框中的行数。

    我会这样做

    data['IB_Low_Break'] = data['Last'].map(lambda i:  i < IB_low);
    

    【讨论】:

    • 我在使用您的代码 Asagen 时收到 TypeError: len() of unsized object
    • 对不起,我的错,我认为IB_low 是一个常数,而不是一个系列。如果IB_lowdata 具有相同的行索引,那么您可以执行类似data.apply(lambda i: i['Last'] &gt; IB_low.loc[i.name],axis=1) 的操作。如果行索引不同,您可以通过以下方式将它们设置为相同:IB_low.index = data.index
    • 我试过你的代码但得到ValueError: Length mismatch: Expected axis has 7 elements, new values have 1774 elements
    • 嗨,这就是为什么我试图提供一个包含数据的工作示例(pickle 文件)。
    • 下次你总是可以构建一个不需要包含腌制对象的玩具示例。无论如何,我的问题是我不太了解您正在使用的对象。我假设IB_low 是一个系列,data 是一个与IB_low 具有相同行数的DataFrame
    猜你喜欢
    • 2020-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-29
    相关资源
    最近更新 更多