【问题标题】:Python 2.7 Pandas: How to replace a for-loop?Python 2.7 Pandas:如何替换 for 循环?
【发布时间】:2014-06-28 08:56:52
【问题描述】:

我有一个包含 2000 行(每行一个日期)和 2000 列(1 秒间隔)的大型 pandas 数据框。每个单元格代表一个温度读数。

从第 5 行开始,我需要返回 5 行并找到行中第 1 列高于行中第 2 列的所有观察值。

对于第 5 行,我可能会发现 2 个这样的观察结果。然后,我想对观察结果进行汇总统计,并将这些汇总统计信息附加到列表中。

然后我转到第 6 行并返回 5 行,找到第 1 列高于第 2 列的所有 obv。我得到所有的 obvs,对 obvs 进行汇总统计并将结果附加到新的数据框。

因此,对于数据框中的每一行,我想返回 5 天,获取 obvs,获取统计信息,并将统计信息附加到数据框中。

问题是,如果我对第 5 -2000 行执行此操作,那么我将有一个 1995 个周期长的 for 循环,这需要一段时间。

有什么更好或最好的方法来做到这一点?

代码如下:

print huge_dataframe

            sec_1    sec_2   sec_3   sec_4   sec_5
2013_12_27   0.05     0.12    0.06    0.15    0.14
2013_12_28   0.06     0.32    0.56    0.14    0.17
2013_12_29   0.07     0.52    0.36    0.13    0.13
2013_12_30   0.02     0.12    0.16    0.55    0.12
2013_12_31   0.06     0.30    0.06    0.14    0.01
2014_01_01   0.05     0.12    0.06    0.15    0.14
2014_01_02   0.06     0.32    0.56    0.14    0.17
2014_01_03   0.07     0.52    0.36    0.13    0.13
2014_01_04   0.02     0.12    0.16    0.55    0.12
2014_01_05   0.06     0.30    0.06    0.14    0.01


for each row in huge_dataframe.ix[5:]:

    move = row[sec_1] - row[sec_2]
    if   move < 0: move = 'DOWN'
    elif move > 0: move = 'UP'

    relevant_dataframe = huge_dataframe.ix[only the 5 rows preceding the current row]


        if   move == 'UP':
            mask = relevant_dataframe[sec_1 < sec_2]   # creates a boolean dataframe
            observations_df = relevant_dataframe[mask]

        elif move == 'DOWN':
            mask = relevant_dataframe[sec_1 > sec_2]   # creates a boolean dataframe
            observations_df = relevant_dataframe[mask]

        # At this point I have observations_df which is only filled
        # with rows where sec_1 < sec_2 or the opposite, depending on which 
        # row I am in. 

        summary_stats = str(observations_df.describe())
        summary_list.append(summary_stats)               # This is the goal 
                                                         # I want to ultimatly
                                                         # turn the list into a 
                                                         # dataframe

【问题讨论】:

  • 请说得更清楚。最理想的情况是,您希望提供代码。将 500 更改为 5,将 40 更改为 for,您至少可以在一个简单的 10 x 10 数据框(左右)中显示您的数据是什么样的,以及预期的输出(至少是其中的一部分)是什么。
  • 另外,您可以编写(假)代码,在“for 循环”中显示您尝试以不同方式实现的目标。
  • 我认为您的第二个if-else 部分中的huge_dataframe 应该是relevant_dataframe,对吧?
  • 是的,你是对的。我改了。

标签: python-2.7 for-loop pandas scipy dataframe


【解决方案1】:

由于没有用于创建数据的代码,我将仅勾画我将尝试使其工作的代码。通常,尽可能避免按行操作。我一开始也不知道,但后来我产生了兴趣,一些研究产生了TimeGrouper

df = big_dataframe
df['move'] = df['sec_1'] > df['sec2']
def foobarRules(group):
    # keep in mind that in here, you refer not to "relevant_dataframe", but to "group"
    if (group.tail(1).move == True):
        # some logic
    else:
        # some other logic

    return str(group.describe())

grouper = TimeGrouper('5D')
allMyStatistics = df.groupby(grouper).apply(foobarRules)

如果您返回多维数据框,我真的不知道返回是如何工作的。我知道如果您返回一行或一列效果很好,但是如果您返回一个包含每个组的行和列的数据框 - 我猜 pandas 足够聪明,可以计算所有这些面板。好吧,你会发现的。

【讨论】:

  • 如果可行,请随时使用一些工作代码进行更新。我很想看看结果。
  • 不,这几乎不会。这不是滚动窗口操作。你只会得到两个不重叠的窗口:2013-12-27 和 2014-01-01
  • 对。然后看看rolling_apply。它的缺点是它所采用的函数显然只允许返回一个值。我自己会玩一会儿,但我现在不在工作地点。
猜你喜欢
  • 2017-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-17
  • 2019-03-07
  • 1970-01-01
  • 2022-01-14
  • 2011-09-22
相关资源
最近更新 更多