天道酬勤,学无止境

How to look back at previous rows from within Pandas dataframe function call?

I am researching/backtesting a trading system.

I have a Pandas dataframe containing OHLC data and have added several calculated columns which identify price patterns that I will use as signals to initiate positions.

I would now like to add a further column that will keep track of the current net position. I have tried using df.apply(), but passing the dataframe itself as the argument instead of the row object, as with the latter I seem to be unable to look back at previous rows to determine whether they resulted in any price patterns:

open_campaigns = []
Campaign = namedtuple('Campaign', 'open position stop')

def calc_position(df):
  # sum of current positions + any new positions

  if entered_long(df):
    open_campaigns.add(
        Campaign(
            calc_long_open(df.High.shift(1)), 
            calc_position_size(df), 
            calc_long_isl(df)
        )
    )

  return sum(campaign.position for campaign in open_campaigns)

def entered_long(df):
  return buy_pattern(df) & (df.High > df.High.shift(1))

df["Position"] = df.apply(lambda row: calc_position(df), axis=1)

However, this returns the following error:

ValueError: ('The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()', u'occurred at index 1997-07-16 08:00:00')

Rolling window functions would seem to be the natural fit, but as I understand it, they only act on a single time series or column, so wouldn't work either as I need to access the values of multiple columns at multiple timepoints.

How should I in fact be doing this?

评论

This problem has its roots in NumPy.

def entered_long(df):
  return buy_pattern(df) & (df.High > df.High.shift(1))

entered_long is returning an array-like object. NumPy refuses to guess if an array is True or False:

In [48]: x = np.array([ True,  True,  True], dtype=bool)

In [49]: bool(x)

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

To fix this, use any or all to specify what you mean for an array to be True:

def calc_position(df):
  # sum of current positions + any new positions

  if entered_long(df).any():  # or .all()

The any() method will return True if any of the items in entered_long(df) are True. The all() method will return True if all the items in entered_long(df) are True.

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • How to calculate difference on previous within set of grouped rows in a dataframe
    I'm looking for help with this simultaneous group-by / row-on-row difference problem in Pandas. The problem is exactly as stated here for R: How to calculate time difference between datetimes, for each group (student-contract)? I have data like this: # USER_ID CONTRACT_REF SUBMISSION_DATE 1 1 A 20/6 01:00 2 1 A 20/6 02:00 3 1 B 20/6 03:00 4 4 A 20/6 04:00 5 5 A 20/6 05:00 6 5 B 20/6 06:00 7 7 A 20/6 07:00 8 7 B 20/6 08:00 9 7 B 20/6 09:30 10 7 B 20/6 10:00 I want to calculate the time difference from the previous submission for each unique USER_ID - CONTRACT_REF pair. Note: each USER_ID -
  • 如何计算数据帧中一组分组行中先前的差异(How to calculate difference on previous within set of grouped rows in a dataframe)
    问题 我正在寻找有关 Pandas 中此同时分组/行对行差异问题的帮助。 问题与此处所述的 R 完全相同:如何计算每个组(学生合同)的日期时间之间的时差? 我有这样的数据: # USER_ID CONTRACT_REF SUBMISSION_DATE 1 1 A 20/6 01:00 2 1 A 20/6 02:00 3 1 B 20/6 03:00 4 4 A 20/6 04:00 5 5 A 20/6 05:00 6 5 B 20/6 06:00 7 7 A 20/6 07:00 8 7 B 20/6 08:00 9 7 B 20/6 09:30 10 7 B 20/6 10:00 我想计算每个唯一的 USER_ID - CONTRACT_REF 对与上一次提交的时间差。 注意:每个 USER_ID - CONTRACT_REF 对的第一次出现都必须为零(或空值)。 所以输出应该如下所示: # USER_ID CONTRACT_REF SUBMISSION_DATE TIME_DIFFERENCE 1 1 A 20/6 01:00 0 2 1 A 20/6 02:00 1 3 1 B 20/6 03:00 0 4 4 A 20/6 04:00 0 5 5 A 20/6 05:00 0 6 5 B 20/6 06:00 0 7 7 A 20/6 07:00 0 8 7 A 20
  • 数据分析之Pandas合并操作总结
    pandas 是一个强大的分析结构化数据的工具集,它的使用基础是Numpy(提供高性能的矩阵运算),用于数据挖掘和数据分析,同时也提供数据清洗功能。Pandas做分析数据,可以分为索引、分组、变形及合并四种操作。前边已经介绍过索引操作 、分组操作及变形操作,最后对Pandas中的合并操作进行介绍,涉及知识点提纲如下图: 本文目录 1. append与assign 1.1. append方法 1.2. assign方法2. combine与update 2.1. combine方法 2.2. update方法 3. concat方法 4. merge与join 4.1. merge函数 4.2. join函数在详细讲解每个模块之前,首先读入数据:import numpy as npimport pandas as pddf = pd.read_csv('joyful-pandas-master/data/table.csv')df.head()append与assign1. append方法(一般用来添加行)(1)利用序列添加行(必须指定name)df_append = df.loc[:3,['Gender','Height']].copy() # 默认深拷贝df_appends = pd.Series({'Gender':'F','Height':188},name='new
  • 如何在Pandas的DataFrame中的行上进行迭代(How to iterate over rows in a DataFrame in Pandas)
    问题 我有一个来自Pandas的DataFrame : import pandas as pd inp = [{'c1':10, 'c2':100}, {'c1':11,'c2':110}, {'c1':12,'c2':120}] df = pd.DataFrame(inp) print df 输出: c1 c2 0 10 100 1 11 110 2 12 120 现在,我要遍历该框架的行。 对于每一行,我希望能够通过列名访问其元素(单元格中的值)。 例如: for row in df.rows: print row['c1'], row['c2'] 在熊猫市有可能做到这一点吗? 我发现了这个类似的问题。 但这并不能给我我所需要的答案。 例如,建议在那里使用: for date, row in df.T.iteritems(): 或者 for row in df.iterrows(): 但是我不明白什么是row对象以及如何使用它。 回答1 DataFrame.iterrows是一个生成器,它同时生成索引和行(作为系列): import pandas as pd df = pd.DataFrame({'c1': [10, 11, 12], 'c2': [100, 110, 120]}) for index, row in df.iterrows(): print(row['c1']
  • Fastest way to compare row and previous row in pandas dataframe with millions of rows
    I'm looking for solutions to speed up a function I have written to loop through a pandas dataframe and compare column values between the current row and the previous row. As an example, this is a simplified version of my problem: User Time Col1 newcol1 newcol2 newcol3 newcol4 0 1 6 [cat, dog, goat] 0 0 0 0 1 1 6 [cat, sheep] 0 0 0 0 2 1 12 [sheep, goat] 0 0 0 0 3 2 3 [cat, lion] 0 0 0 0 4 2 5 [fish, goat, lemur] 0 0 0 0 5 3 9 [cat, dog] 0 0 0 0 6 4 4 [dog, goat] 0 0 0 0 7 4 11 [cat] 0 0 0 0 At the moment I have a function which loops through and calculates values for 'newcol1' and 'newcol2'
  • How can I construct a Pandas DataFrame from individual 1D Numpy arrays without copying
    Unlike every other question I can find, I do not want to create a DataFrame from a homogeneous Numpy array, nor do I want to convert a structured array into a DataFrame. What I want is to create a DataFrame from individual 1D Numpy arrays for each column. I tried the obvious DataFrame({"col": nparray, "col": nparray}), but this shows up at the top of my profile, so it must be doing something really slow. It is my understanding that Pandas DataFrames are implemented in pure Python, where each column is backed by a Numpy array, so I would think there is an efficient way to do it. What I'm
  • Getting previous row values from within pandas apply() function
    import pandas as pd def greater_or_less(d): if d['current'] > d['previous']: d['result']="Greater" elif d['current'] < d['previous']: d['result']="Less" elif d['current'] == d['previous']: d['result']="Equal" else: pass return d df=pd.DataFrame({'current':[1,2,2,8,7]}) # Duplicate the column with shifted values df['previous']=df['current'].shift(1) df['result']="" df=df.apply(greater_or_less,axis=1) The result is: current previous result 1 NaN 2 1 Greater 2 2 Equal 8 2 Greater 7 8 Less I'd then drop the previous column as it's no longer needed. Ending up with: current result 1 2 Greater 2
  • 如何在for循环中在pandas数据框中追加行?(How to append rows in a pandas dataframe in a for loop?)
    问题 我有以下for循环: for i in links: data = urllib2.urlopen(str(i)).read() data = json.loads(data) data = pd.DataFrame(data.items()) data = data.transpose() data.columns = data.iloc[0] data = data.drop(data.index[[0]]) 这样创建的每个数据框都具有与其他列相同的大多数列,但不是全部。 而且,它们都只有一行。 我需要的是将for循环产生的每个数据帧的所有不同列和每一行添加到数据帧中 我尝试了串联或类似的大熊猫,但似乎没有任何效果。 任何想法? 谢谢。 回答1 假设您的数据如下所示: import pandas as pd import numpy as np np.random.seed(2015) df = pd.DataFrame([]) for i in range(5): data = dict(zip(np.random.choice(10, replace=False, size=5), np.random.randint(10, size=5))) data = pd.DataFrame(data.items()) data = data.transpose() data
  • 向量化熊猫中的函数(Vectorizing a function in pandas)
    问题 我有一个包含经纬度坐标列表的数据框: d = {'Provider ID': {0: '10001', 1: '10005', 2: '10006', 3: '10007', 4: '10008', 5: '10011', 6: '10012', 7: '10016', 8: '10018', 9: '10019'}, 'latitude': {0: '31.215379379000467', 1: '34.22133455500045', 2: '34.795039606000444', 3: '31.292159523000464', 4: '31.69311635000048', 5: '33.595265517000485', 6: '34.44060759100046', 7: '33.254429322000476', 8: '33.50314015000049', 9: '34.74643089500046'}, 'longitude': {0: ' -85.36146587999968', 1: ' -86.15937514799964', 2: ' -87.68507485299966', 3: ' -86.25539902199966', 4: ' -86.26549483099967', 5: ' -86.66531866799966', 6: '
  • 如何将空列添加到数据框?(How to add an empty column to a dataframe?)
    问题 将空列添加到pandas DataFrame对象的最简单方法是什么? 我偶然发现的最好的东西是 df['foo'] = df.apply(lambda _: '', axis=1) 有没有那么不合常理的方法? 回答1 如果我理解正确,则应填写作业: >>> import numpy as np >>> import pandas as pd >>> df = pd.DataFrame({"A": [1,2,3], "B": [2,3,4]}) >>> df A B 0 1 2 1 2 3 2 3 4 >>> df["C"] = "" >>> df["D"] = np.nan >>> df A B C D 0 1 2 NaN 1 2 3 NaN 2 3 4 NaN 回答2 为了增加DSM的答案并以这个相关问题为基础,我将该方法分为两种情况: 添加单个列:只需将空值分配给新列,例如df['C'] = np.nan 添加多列:我建议使用.reindex(columns=[...])方法将新列添加到数据框的列索引中。 这也适用于使用.reindex(rows=[...])添加多个新行。 请注意,较新版本的Pandas(v> 0.20)允许您指定axis关键字,而不是显式分配给columns或rows 。 这是添加多列的示例: mydf = mydf.reindex(columns =
  • 为什么熊猫申请两次计算(Why does pandas apply calculate twice)
    问题 我在熊猫的DataFrame对象上使用apply方法。 当我的DataFrame只有一列时,似乎应用的函数被调用了两次。 问题是为什么? 而且,我可以停止这种行为吗? 代码: import pandas as pd def mul2(x): print ('hello') return 2*x df = pd.DataFrame({'a': [1,2,0.67,1.34]}) df.apply(mul2) 输出: hello hello 0 2.00 1 4.00 2 1.34 3 2.68 我正在从要应用的函数中打印“ hello”。 我知道它被应用了两次,因为“ hello”打印了两次。 更重要的是,如果我有两列,“ hello”将打印3次。 当我调用仅应用于列“ hello”时,将打印4次甚至更多。 代码: df.a.apply(mul2) 输出: hello hello hello hello 0 2.00 1 4.00 2 1.34 3 2.68 Name: a, dtype: float64 回答1 此行为已在pandas 1.1中修复,请升级! 现在,对DataFrame的apply和applymap仅对第一行/列求值一次。 最初,我们让GroupBy.apply和Series/df.apply对第一组进行两次评估。 第一组进行两次评估的原因是
  • 如何将Pandas Dataframe写入Django模型(How to write a Pandas Dataframe to Django model)
    问题 我一直在使用python中的pandas,通常将数据帧写入数据库表,如下所示。 我现在正在迁移到Django,如何通过称为MyModel的模型将相同的数据帧写入表中? 援助真的很感激。 # Original pandas code engine = create_engine('postgresql://myuser:mypassword@localhost:5432/mydb', echo=False) mydataframe.to_sql('mytable', engine,if_exists='append',index=True) 回答1 在映射到同一SQL表的Django模型旁边使用自己的熊猫代码 我不知道将熊猫数据框写入Django模型的任何明确支持。 但是,在Django应用中,除了使用ORM(例如通过Django模型)之外,您仍然可以使用自己的代码来读取或写入数据库。 并且鉴于您极有可能以前在数据库中由pandas的to_sql编写了数据,因此您可以继续使用相同的数据库和相同的pandas代码,只需创建一个可以访问该表的Django模型 例如,如果您的熊猫代码正在写入SQL表mytable ,则只需创建一个这样的模型: class MyModel(Model): class Meta: db_table = 'mytable' # This tells
  • 在熊猫数据框中找到条纹(finding streaks in pandas dataframe)
    问题 我有一个熊猫数据框,如下所示: time winner loser stat 1 A B 0 2 C B 0 3 D B 1 4 E B 0 5 F A 0 6 G A 0 7 H A 0 8 I A 1 每行都是一个匹配结果。 第一列是比赛的时间,第二和第三列是获胜者/失败者,第四列是比赛的一个统计数据。 我想为每个失败者将此统计数据检测为零。 预期结果应如下所示: time winner loser stat streak 1 A B 0 1 2 C B 0 2 3 D B 1 0 4 E B 0 1 5 F A 0 1 6 G A 0 2 7 H A 0 3 8 I A 1 0 在伪代码中,算法应像这样工作: .groupby loser列。 然后遍历每个loser群体的每一行在每一行中,查看stat列:如果它包含0 ,则将前一行的streak值增加0 。 如果它不是0 ,则开始一个新的streak ,即将0放入streak列。 因此.groupby很清楚。 但是然后我需要某种.apply来查看上一行吗? 这就是我被困住的地方。 回答1 不像jezrael的回答那么优雅,但对我来说更容易理解... 首先,定义一个可以处理单个失败者的函数: def f(df): df['streak2'] = (df['stat'] == 0).cumsum() df['cumsum']
  • 熊猫可以在不修改文件其余部分的情况下读取和修改单个Excel文件工作表(标签)吗?(Can Pandas read and modify a single Excel file worksheet (tab) without modifying the rest of the file?)
    问题 许多电子表格具有公式和格式,用于读取和写入Excel文件的Python工具无法如实复制。 这意味着我要以编程方式创建的任何文件都必须基本上是我从头开始创建的文件,然后其他Excel文件(具有上述复杂性)必须引用该文件(这会导致各种其他依赖项问题)。 我对Excel文件“标签”的理解是它们实际上只是XML文件的集合。 好吧,是否可以使用熊猫(或诸如xlsxwriter或openpyxl之类的底层读写引擎之一来仅修改选项卡之一,而保留其他选项卡(其中包含更多邪恶的东西))? 编辑:我将尝试通过一个例子进一步阐明问题。 Excel工作表test.xlsx具有四个选项卡(又名工作表):Sheet1,Sheet2,Sheet3,Sheet4 我使用pandas.read_excel()将Sheet3读入DataFrame(我们称其为df) Sheet1和Sheet2包含公式,图形和openpyxl或xlrd都无法成功解析的各种格式,Sheet4包含其他数据。 我根本不想触摸这些标签。 Sheet2实际上对Sheet3上的单元格有一些引用我对df进行了一些编辑,现在想将其写回到sheet3,而其他工作表保持不变(工作簿中其他工作表对它的引用也保持不变) 我可以这样做吗?如果可以,怎么办? 回答1 关于excel和python(尤其是pandas)之间的交互,我有一个类似的问题
  • Iterate through a list of dataframes to drop particular rows Pandas
    In my previous question where I asked to drop particular rows in Pandas With help, I was to drop rows that before 1980. The 'Season' column (that had the years) were in this format: 2018-19 2017-18 This list would go till 1960 In the earlier question(linked) @jezrael gave a solution that helped me drop rows before 1980. I have a list (called list) that has 30 dataframes. I want to iterate through the 30 dataframes and drop all rows before 1980 for every df. For instance, one of the items in list is BOS if BOS['Season] has: 2018-19 2017-18 1959-1960 I should get 2018-19 2017-18 And the result
  • 如何删除在特定列中的值为NaN的Pandas DataFrame行(How to drop rows of Pandas DataFrame whose value in a certain column is NaN)
    问题 我有这个DataFrame ,只想要EPS列不是NaN的记录: >>> df STK_ID EPS cash STK_ID RPT_Date 601166 20111231 601166 NaN NaN 600036 20111231 600036 NaN 12 600016 20111231 600016 4.3 NaN 601009 20111231 601009 NaN NaN 601939 20111231 601939 2.5 NaN 000001 20111231 000001 NaN NaN ...例如df.drop(....)类的东西来获取结果数据df.drop(....) : STK_ID EPS cash STK_ID RPT_Date 600016 20111231 600016 4.3 NaN 601939 20111231 601939 2.5 NaN 我怎么做? 回答1 不要丢掉,只取EPS不是NA的行: df = df[df['EPS'].notna()] 回答2 这个问题已经解决,但是... ...还要考虑伍特(Wouter)在其原始评论中提出的解决方案。 大熊猫内置了处理丢失数据(包括dropna() 。 除了通过手动执行可能会提高的性能外,这些功能还带有多种可能有用的选项。 In [24]: df = pd.DataFrame(np
  • 如何从数据框中删除空格/ NA,并将值上移(How to remove blanks/NA's from dataframe and shift the values up)
    问题 我有一个巨大的数据框,里面有值和空白/ NA。 我想从数据框中删除空格,并在列中向上移动下一个值。 考虑下面的示例数据框。 import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(5,4)) df.iloc[1,2] = np.NaN df.iloc[0,1] = np.NaN df.iloc[2,1] = np.NaN df.iloc[2,0] = np.NaN df 0 1 2 3 0 1.857476 NaN -0.462941 -0.600606 1 0.000267 -0.540645 NaN 0.492480 2 NaN NaN -0.803889 0.527973 3 0.566922 0.036393 -1.584926 2.278294 4 -0.243182 -0.221294 1.403478 1.574097 我希望我的输出如下 0 1 2 3 0 1.857476 -0.540645 -0.462941 -0.600606 1 0.000267 0.036393 -0.803889 0.492480 2 0.566922 -0.221294 -1.584926 0.527973 3 -0.243182 1.403478 2.278294 4 1.574097
  • 熊猫:错误的行的位置(Pandas: Location of a row with error)
    问题 我是Pandas的新手,并试图找出我的代码在哪里中断。 说,我正在做一个类型转换: df['x']=df['x'].astype('int') ...并且我得到一个错误“ ValueError:以10为基数的long()的无效文字:'1.0692e + 06' 通常,如果我在数据框中有1000个条目,那么我如何找出导致中断的条目。 ipdb中是否有什么可以输出当前位置(即代码中断的位置)? 基本上,我试图确定不能将哪些值转换为Int。 回答1 您看到的错误可能是由于x列中的值为字符串: In [15]: df = pd.DataFrame({'x':['1.0692e+06']}) In [16]: df['x'].astype('int') ValueError: invalid literal for long() with base 10: '1.0692e+06' 理想的情况下,可以通过确保存储在数据帧的值来避免这个问题已经不是整数的字符串时,数据帧建成。 如何做到这一点当然取决于您如何构建DataFrame。 之后,可以使用applymap修复DataFrame: import ast df = df.applymap(ast.literal_eval).astype('int') 但是在ast.literal_eval中的每个值上调用ast.literal
  • 利用python进行数据分析学习笔记
    利用python进行数据分析 numpy:数组与向量化计算pandaspandas读取和写入数据集及文件格式数据清洗与准备数据规整:连接、联合和重排列绘图与可视化数据聚合与分组操作时间序列高阶pandasPython建模库介绍高阶numpy 本篇是《利用python进行数据分析》的学习笔记。 numpy:数组与向量化计算 ndarray,一种高效多维数组,提供了基于数组的便捷算术操作以及灵活的广播功能。对所有数据进行快速的矩阵计算,而无需编写循环程序。对硬盘中的数组数据进行读写的工具,并对映射文件进行操作。线性代数,随机数生成和傅里叶变换功能。用于连接numpy到C/C++类库的C语言API。 numpy本身并不提供建模和科学函数,理解numpy的数组以及基于数组的计算将帮助更高效的使用基于数组的工具,如pandas。 对于大多数数据分析应用,要关注在数据处理、清洗、构造子集、过滤、变换以及其他运算中进行快速的向量化计算。 常见的数组算法,sort、unique以及set操作。高效的描述性统计和聚合数据。数据排列和相关数据操作,如对异构数据进行merge和join。使用数组表达式来表明条件逻辑。分组数据的操作:聚合、变换、函数式操作。 numpy的设计对与含有大量数组的数据非常有效;numpy在内部将数据储存在连续的内存块上;numpy算法库使用C语言写,所以在操作数据内存时
  • 不能用dropna在熊猫中丢掉NAN(Can't drop NAN with dropna in pandas)
    问题 我将pandas导入为pd并运行以下代码,并获得以下结果 代码: traindataset = pd.read_csv('/Users/train.csv') print traindataset.dtypes print traindataset.shape print traindataset.iloc[25,3] traindataset.dropna(how='any') print traindataset.iloc[25,3] print traindataset.shape 输出 TripType int64 VisitNumber int64 Weekday object Upc float64 ScanCount int64 DepartmentDescription object FinelineNumber float64 dtype: object (647054, 7) nan nan (647054, 7) [Finished in 2.2s] 从结果来看,dropna行不起作用,因为行号没有更改,并且数据帧中仍然存在NAN。 怎么会这样我现在疯了。 回答1 您需要阅读文档(添加了重点): 返回对象,省略给定轴上的标签 dropna返回一个新的DataFrame。 如果您希望它修改现有的DataFrame,则您需要做的所有事情都在文档中进一步阅读: