【问题标题】:Iterating through DataFrame using pandas for stocks使用 pandas 遍历 DataFrame 的股票
【发布时间】:2016-06-16 03:20:15
【问题描述】:

我对 python 和 pandas 比较陌生。 我有一个DataFrame,上面有几只股票及其过去几天相关的“低价”价格。我正在尝试遍历每只股票(现在我只有 3 只,但最终会有数千只),然后对于每只股票,我想看看当天的“低价”价格是否大于昨天的低价,我想看看如果昨天的低价低于两天前的低价。对于满足此条件的每只股票,我最终都希望将它们导出到 csv 文件。

list = ['IBM', 'AMZN', 'FB'] 

stockData = DataReader(list,  'yahoo', datetime(2016,06,8), datetime.today().utcnow())

low = stockData['Low']

low0 = low.iloc[-1]
low1 = low.iloc[-2]
low2 = low.iloc[-3]

变量 low0、low1 和 low2 可能不是必需的,但我确实喜欢它们如何拼接出我想要的特定数据。

然后我尝试用我的函数迭代列表中的每只股票:

for stock in list:
    if low0 > low1 and low1 < low2:
        print True
    else: 
        print False

这是我得到的错误: ValueError:Series 的真值不明确。使用 a.empty、a.bool()、a.item()、a.any() 或 a.all()。

如有任何意见,我将不胜感激。

【问题讨论】:

    标签: python pandas datareader


    【解决方案1】:

    这是一个类似但略有不同的解决此问题的方法的示例。我使用虚拟值来演示。

    首先,我创建一个数据框。

    dates = pd.date_range('20130101', periods=3)
    IBM = [5,3,2]
    AMZN = [1,7,6]
    FB = [4,7,9]
    df = pd.DataFrame({'IBM': IBM,'AMZN': AMZN,'FB':FB}, index=dates)
    df
              AMZN  FB  IBM
    2013-01-01  1   4   5
    2013-01-02  7   7   3
    2013-01-03  6   9   2
    

    我使用.shift() 来跟踪与数据框中的第一天和第二天相比,第二天和第三天的值上升或下降了多少。我通过从df 中减去df.shift(1) 来做到这一点。第一天的值将替换为NaN

    df - df.shift(1)
               AMZN     FB     IBM
    2013-01-01  NaN     NaN     NaN  
    2013-01-02  6.0     3.0     -2.0
    2013-01-03  -1.0    2.0     -1.0
    

    如果您更喜欢TrueFalse,您可以检查这些值是高于还是低于0。因此,在这种情况下,True 表示向上,False 表示向下,第一天的起始值将替换为 False

    df - df.shift(1) > 0
                AMZN    FB      IBM
    2013-01-01  False   False   False
    2013-01-02  True    True    False
    2013-01-03  False   True    False 
    

    【讨论】:

      【解决方案2】:

      要确定Low 在过去三天内是否一直在增加,您可以使用以下命令:

      stockData = stockData.sort_index(ascending=False).iloc[:3] # reverse order, use last three days
      

      比较相邻日期之间的Low 的条件之一,如果Low 在这两种情况下都在增加,则返回True

      stockData[(stockData.Low < stockData.Low.shift(1)) & (stockData.Low.shift(1) < stockData.Low.shift(2))]
      

      或者检查最后三个 Low 价格之间的差值是否为负数(因为现在是最近的一天):

      stockData.Low.diff().dropna() < 0).all()
      

      所以对于您的应用程序:

      for stock in ['IBM', 'AMZN', 'FB']:
          stockData = DataReader(stock, 'yahoo', datetime(2016, 6, 8), datetime.today().utcnow()).sort_index(ascending=False).iloc[:3]
          print('\n', stockData.Low)
          print(stock, (stockData.Low.diff().dropna()<0).all())
          print(stock, stockData[(stockData.Low < stockData.Low.shift(1)) & (stockData.Low.shift(1) < stockData.Low.shift(2))].Low.any())
      
      
       Date
      2016-06-15    150.600006
      2016-06-14    150.399994
      2016-06-13    150.279999
      Name: Low, dtype: float64
      IBM True
      IBM True
      
       Date
      2016-06-15    713.349976
      2016-06-14    712.270020
      2016-06-13    711.159973
      Name: Low, dtype: float64
      AMZN True
      AMZN True
      
       Date
      2016-06-15    114.070000
      2016-06-14    113.580002
      2016-06-13    113.309998
      Name: Low, dtype: float64
      FB True
      FB True
      

      【讨论】:

      • 执行此操作时出现此错误:ValueError: Cannot index with multidimensional key
      • 不确定,您是直接从DataReader 使用stockData 吗?修复了条件,现在2016-05-11 是正确的结果,前两天的Low 价格较低。
      • 好的。我明白你在做什么,这不是我想要做的。我正在尝试查看是否满足这些标准并得到 True 或 False。 if low0 > low1 and low1
      • 您的意思是True,如果有单个案例满足该期间的条件?只需在条件语句中添加.any(),请参阅更新。
      • 不,实际上它必须满足两个条件,而不仅仅是一个。谢谢。
      猜你喜欢
      • 2018-12-28
      • 2023-03-24
      • 2021-09-19
      • 1970-01-01
      • 2019-11-14
      • 2014-10-17
      • 2019-09-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多