【问题标题】:Calculating difference between two rows in Python / Pandas在 Python / Pandas 中计算两行之间的差异
【发布时间】:2020-06-26 04:10:49
【问题描述】:

在 python 中,我如何引用前一行并针对它进行计算?具体来说,我正在与pandas 中的dataframes 合作 - 我有一个充满股票价格信息的数据框,如下所示:

           Date   Close  Adj Close
251  2011-01-03  147.48     143.25
250  2011-01-04  147.64     143.41
249  2011-01-05  147.05     142.83
248  2011-01-06  148.66     144.40
247  2011-01-07  147.93     143.69

这是我创建此数据框的方式:

import pandas

url = 'http://ichart.finance.yahoo.com/table.csv?s=IBM&a=00&b=1&c=2011&d=11&e=31&f=2011&g=d&ignore=.csv'
data = data = pandas.read_csv(url)

## now I sorted the data frame ascending by date 
data = data.sort(columns='Date')

从第 2 行开始,或者在这种情况下,我猜它是 250(PS - 那是索引吗?),我想为每个条目计算 2011-01-03 和 2011-01-04 之间的差异在这个数据框中。我相信适当的方法是编写一个获取当前行的函数,然后计算前一行,并计算它们之间的差异,使用 pandas apply 函数用值更新数据框。

这是正确的方法吗?如果是这样,我应该使用索引来确定差异吗? (注意 - 我仍然处于 python 初学者模式,所以 index 可能不是正确的术语,甚至不是正确的实现方式)

【问题讨论】:

  • 仅仅找到两个日期的行并计算它们之间的差异是不够的..?
  • @redShadow 有趣的想法。我没有这样想过。我看到的唯一问题是您将如何处理周末?有 252 个交易日,不是 365 个。如果你尝试上涨 1 天,并且是周末,该功能将失败。虽然,我想你可以在函数中进行一些错误处理......
  • 不,等等.. 你到底想完成什么?为数据集中的所有记录计算每一天与前一天的差异......?
  • @redShadow 完全正确。逐行,与前一天的差异。第一行将是 0,所以我必须弄清楚一些错误处理,但是......

标签: python pandas


【解决方案1】:

我想你想做这样的事情:

In [26]: data
Out[26]: 
           Date   Close  Adj Close
251  2011-01-03  147.48     143.25
250  2011-01-04  147.64     143.41
249  2011-01-05  147.05     142.83
248  2011-01-06  148.66     144.40
247  2011-01-07  147.93     143.69

In [27]: data.set_index('Date').diff()
Out[27]: 
            Close  Adj Close
Date                        
2011-01-03    NaN        NaN
2011-01-04   0.16       0.16
2011-01-05  -0.59      -0.58
2011-01-06   1.61       1.57
2011-01-07  -0.73      -0.71

【讨论】:

  • 很好,但是您如何将其添加为数据中的新列?
  • @Chang She,如果我不想要差异而是实际值怎么办。也就是说,不是 diff(1),而是 value(1) 或 value(1:3).mean()。第二个组成的示例将获得下一个、第二个和第三个值的平均值。那会很有用
  • .shift() in pandas 为您提供值。
  • 感谢您的回答。对于想要n天差的朋友,值得一提的是,可以将输入参数periods设置为n。查看pandas.DataFrame.diff 文档了解更多详细信息:pandas.pydata.org/pandas-docs/stable/generated/…。
  • 如果你想将差值保存在另一列,你可以:df['close_diff'] = df['Close'].diff()
【解决方案2】:

计算一列的差异。这是你可以做的。

df=
      A      B
0     10     56
1     45     48
2     26     48
3     32     65

我们只想计算 A 中的行差异,并想考虑小于 15 的行。

df['A_dif'] = df['A'].diff()
df=
          A      B      A_dif
    0     10     56      Nan
    1     45     48      35
    2     26     48      19
    3     32     65      6
df = df[df['A_dif']<15]

df=
          A      B      A_dif
    0     10     56      Nan
    3     32     65      6

【讨论】:

    【解决方案3】:

    我不了解 pandas,而且我很确定它有一些特定的东西;但是,我会给你一个纯 Python 的解决方案,即使你需要使用 pandas,它也可能会有所帮助:

    import csv
    import urllib
    
    # This basically retrieves the CSV files and loads it in a list, converting
    # All numeric values to floats
    url='http://ichart.finance.yahoo.com/table.csv?s=IBM&a=00&b=1&c=2011&d=11&e=31&f=2011&g=d&ignore=.csv'
    reader = csv.reader(urllib.urlopen(url), delimiter=',')
    # We sort the output list so the records are ordered by date
    cleaned = sorted([[r[0]] + map(float, r[1:]) for r in list(reader)[1:]])
    
    for i, row in enumerate(cleaned):  # enumerate() yields two-tuples: (<id>, <item>)
        # The try..except here is to skip the IndexError for line 0
        try:
            # This will calculate difference of each numeric field with the same field
            # in the row before this one
            print row[0], [(row[j] - cleaned[i-1][j]) for j in range(1, 7)]
        except IndexError:
            pass
    

    【讨论】:

    • 否决这一点,因为除了重现 pandas 的功能外,它还使用嵌套的 for 循环来完成,这在 Python 中很慢。 Pandas 会在 C 级别做到这一点。
    • downvoting as original question有标签pandas直接指向作者想要解决他的问题的方式
    • 有时你不会知道你想要的东西,直到它呈现给你:)
    • 标题为Python / Pandas。这也可能具有误导性,至少是开始回答的一个理由。在Python pandas 或pandas (Python) 会更好。
    猜你喜欢
    • 2021-12-24
    • 1970-01-01
    • 2019-05-29
    • 2021-01-14
    • 2019-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多