根据前一行中的值操作 pandas 数据框单元格的值,无需迭代

manipulating value of pandas dataframe cell based on value in previous row without iteration

我有一个 pandas 数据框,其中约 3900 行和 6 列是从 Google Finance 编译而来的。这些列之一定义了 unix 格式的时间,具体定义了市场交易日的时间。在这种情况下,DJIA 从 930A EST 到 4P EST。但是,只有每天开始的单元格 (930A) 具有完整的 unix 时间戳(以 'a' 为前缀),其他是一天中第一个时间之后的分钟数。

这里是原始数据的一个例子:

          Date   Close    High     Low    Open  Volume
0  a1450449000  173.87  173.87  173.83  173.87   46987
1            1  173.61  173.83  173.55  173.78   19275
2            2  173.37  173.63  173.37  173.60   16014
3            3  173.50  173.59  173.31  173.34   14198
4            4  173.50  173.57  173.46  173.52    7010
          Date   Close    High     Low    Open  Volume
388          388  171.16  171.27  171.15  171.26   11809
389          389  171.11  171.23  171.07  171.18   30449
390          390  170.89  171.16  170.89  171.09  163937
391  a1450708200  172.28  172.28  172.28  172.28   23880
392            1  172.27  172.27  172.00  172.06    2719

索引 391 处的更改不是连续的,因此不幸的是,@Stefan 之类的解决方案无法正确调整 Date 值。

我可以很容易地使用 lambda 并逐行删除 'a'(如有必要)将值转换为整数并使用以下代码将 930A 之后的分钟数转换为秒数:

import pandas as pd
import numpy as np
import datetime

bars = pd.read_csv(r'http://www.google.com/finance/getprices?i=60&p=10d&f=d,o,h,l,c,v&df=cpct&q=DIA', skiprows=7, header=None, names=['Date', 'Close', 'High', 'Low', 'Open', 'Volume'])

bars['Date'] = bars['Date'].map(lambda x: int(x[1:]) if x[0] == 'a' else int(x))    
bars['Date'] = bars['Date'].map(lambda u: u * 60 if u < 400 else u)

现在我想做的是,在不遍历数据帧的情况下,确定 bars[[=​​34=]] 的值是否不是 unix 时间戳(例如 < 24000 在这个数据集的术语中).如果是这样,我想将该值添加到该特定日期的时间戳,以便为每个条目创建一个完整的 unix 时间戳。

我知道我可以通过以下方式比较上一行:

bars['Date'][:-1]>bars['Date'][1:]

我觉得那是可行的方法,但我想不出在函数中使用它的方法,因为它 returns 是一个系列。

在此先感谢您的帮助!

您可以添加始终包含最新 Timestamp 的新列,然后在必要时添加到 Date

threshold = 24000
bars['Timestamp'] = bars[bars['Date']>threshold].loc[:, 'Date']
bars['Timestamp'] = bars['Timestamp'].fillna(method='ffill')
bars['Date'] = bars.apply(lambda x: x.Date + x.Timestamp if x.Date < threshold else x.Date, axis=1)
bars.drop('Timestamp', axis=1, inplace=True)

获得:

            Date   Close     High     Low    Open  Volume
0     1450449000  173.87  173.870  173.83  173.87   46987
1     1450449060  173.61  173.830  173.55  173.78   19275
2     1450449120  173.37  173.630  173.37  173.60   16014
3     1450449180  173.50  173.590  173.31  173.34   14198
4     1450449240  173.50  173.570  173.46  173.52    7010
5     1450449300  173.66  173.680  173.44  173.45   10597
6     1450449360  173.40  173.670  173.34  173.67   14270
7     1450449420  173.36  173.360  173.13  173.32   22485
8     1450449480  173.29  173.480  173.25  173.36   18542