Pandas DataFrame使用先前的行值来处理复杂的"if"条件以确定当前值

use*_*141 10 python apply dataframe pandas

我想知道是否有更快的方法来执行以下循环?也许使用apply或rolling apply函数来实现这一点基本上,我需要访问前一行的值来确定当前的单元格值.

df.ix[0] = (np.abs(df.ix[0]) >= So) * np.sign(df.ix[0])
for i in range(1, len(df)):
    for col in list(df.columns.values):
        if ((df[col].ix[i] > 1.25) & (df[col].ix[i-1] == 0)) | :
            df[col].ix[i] = 1
        elif ((df[col].ix[i] < -1.25) & (df[col].ix[i-1] == 0)):
            df[col].ix[i] = -1
        elif ((df[col].ix[i] <= -0.75) & (df[col].ix[i-1] < 0)) | ((df[col].ix[i] >= 0.5) & (df[col].ix[i-1] > 0)):
            df[col].ix[i] = df[col].ix[i-1]
        else:
            df[col].ix[i] = 0
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,在函数中,我正在更新数据帧,我需要访问最新的前一行,因此使用shift将无法正常工作.

例如:输入:

A      B     C
1.3  -1.5   0.7
1.1  -1.4   0.6
1.0  -1.3   0.5
0.4   1.4   0.4
Run Code Online (Sandbox Code Playgroud)

输出:

 A      B     C
1     -1      0
1     -1      0
1     -1      0
0      1      0
Run Code Online (Sandbox Code Playgroud)

Max*_*axU 27

您可以使用.shift()函数来访问上一个下一个值:

col列的前一个值:

df['col'].shift()
Run Code Online (Sandbox Code Playgroud)

col列的下一个值:

df['col'].shift(-1)
Run Code Online (Sandbox Code Playgroud)

例:

In [38]: df
Out[38]:
   a  b  c
0  1  0  5
1  9  9  2
2  2  2  8
3  6  3  0
4  6  1  7

In [39]: df['prev_a'] = df['a'].shift()

In [40]: df
Out[40]:
   a  b  c  prev_a
0  1  0  5     NaN
1  9  9  2     1.0
2  2  2  8     9.0
3  6  3  0     2.0
4  6  1  7     6.0

In [43]: df['next_a'] = df['a'].shift(-1)

In [44]: df
Out[44]:
   a  b  c  prev_a  next_a
0  1  0  5     NaN     9.0
1  9  9  2     1.0     2.0
2  2  2  8     9.0     6.0
3  6  3  0     2.0     6.0
4  6  1  7     6.0     NaN
Run Code Online (Sandbox Code Playgroud)

  • 我知道 shift() 函数,但我在整个循环中更新数据帧,所以 shift 不起作用。我需要处理最新的前一行,而不是原始的前一行 (2认同)

Cor*_*ump 8

我很惊讶也没有本地 Pandas 解决方案,因为移位和滚动没有完成。我已经设计了一种使用标准熊猫语法来做到这一点的方法,但我不确定它的性能是否比你的循环更好......我的目的只是为了一致性(而不是速度)。

import pandas as pd

df = pd.DataFrame({'a':[0,1,2], 'b':[0,10,20]})

new_col = 'c'

def apply_func_decorator(func):
    prev_row = {}
    def wrapper(curr_row, **kwargs):
        val = func(curr_row, prev_row)
        prev_row.update(curr_row)
        prev_row[new_col] = val
        return val
    return wrapper

@apply_func_decorator
def running_total(curr_row, prev_row):
    return curr_row['a'] + curr_row['b'] + prev_row.get('c', 0)

df[new_col] = df.apply(running_total, axis=1)

print(df)
# Output will be:
#    a   b   c
# 0  0   0   0
# 1  1  10  11
# 2  2  20  33
Run Code Online (Sandbox Code Playgroud)

免责声明:我使用了 Pandas 0.16,但只需稍作修改,这也适用于最新版本。

其他人也有类似的问题,我也发布了这个解决方案: