Python根据现有列的条件计算新列

时间:2018-11-05 16:10:32

标签: python dataframe conditional-statements multiple-columns

我想根据现有列的某些条件创建一个新列,以下是我现在正在做的事情,但是花费大量时间处理大量数据。有什么有效或更快的方法可以做到这一点。

DF["A"][0] = 0
for x in range(1,rows):
    if(DF["B"][x]>DF["B"][x-1]):
        DF["A"][x] = DF["A"][x-1] + DF["C"][x]
    elif(DF["B"][x]<DF["B"][x-1]):
        DF["A"][x] = DF["A"][x-1] - DF["C"][x]
    else:
        DF["A"][x] = DF["A"][x-1]

2 个答案:

答案 0 :(得分:0)

  

基于现有列的某些条件的新列

我正在使用@zipa提供的DataFrame:

df = pd.DataFrame({'A': [1, 2, 3, 4, 5],
                   'B': [12, 15, 9, 8, 15],
                   'C': [3, 9, 12, 6, 8]})

第一种方法

以下是您指定的有效执行的功能。它利用了熊猫的索引功能,特别是行掩码

def update(df):
    cond_larger = df['B'] > df['B'].shift().fillna(0)
    cond_smaller = df['B'] < df['B'].shift().fillna(0)
    cond_else = ~(cond_larger | cond_smaller)
    for cond, sign in [(cond_larger, +1),  # A[x-1] + C[x] 
                       (cond_smaller, -1), # A[x-1] - C[x]
                       (cond_else, 0)]:    # A[x-1] + 0
        if any(cond):
            df.loc[cond, 'A_updated'] = (df['A'].shift().fillna(0) + 
                                         sign * df[cond]['C'])
    df['A'] = df['A_updated']
    df.drop(columns=['A_updated'], inplace=True)
    return df

update(df)
=> 
      A   B   C
0   3.0  12   3
1  10.0  15   9
2 -10.0   9  12
3  -3.0   8   6
4  12.0  15   8

已优化

事实证明,您可以使用DataFrame.mask来达到上述目的。请注意,您可以将条件合并到mask的调用中,但是我发现这样更容易阅读:

# specify conditions
cond_larger = df['B'] > df['B'].shift().fillna(0)
cond_smaller = df['B'] < df['B'].shift().fillna(0)
cond_else = ~(cond_larger | cond_smaller)
# apply
A_shifted = (df['A'].shift().fillna(0)).copy()
df.mask(cond_larger, A_shifted + df['C'], axis=0, inplace=True)
df.mask(cond_smaller, A_shifted - df['C'], axis=0, inplace=True)
df.mask(cond_else, A_shifted, axis=0, inplace=True)
=>
(same results as above)

注意:

  • 我假设0的默认值为A/B[x-1]。如果应该以不同的方式对待第一行,请删除或替换.fillna(0)。结果会有所不同。

  • 条件将按顺序检查。根据更新是使用A中的原始值还是在先前条件下更新的值,您可能不需要帮助器列A_updated

  • 有关我如何到达这里的历史,请参见此答案的先前版本

答案 1 :(得分:0)

如果我说对了,这就是您想要的:

import pandas as pd
import numpy as np

df = pd.DataFrame({'A': [1, 2, 3, 4, 5],
                   'B': [12, 15, 9, 8, 15],
                   'C': [3, 9, 12, 6, 8]})

df['A'] = np.where(df.index==0,
                   0,
                   np.where(df['B']>df['B'].shift(),
                            df['A']-df['A'].shift(),
                            np.where(df['B']<df['B'].shift(),
                                     df['A'].shift()-df['C'],
                                     df['A'].shift())))
df
#      A   B   C
#0   0.0  12   3
#1   1.0  15   9
#2 -10.0   9  12
#3  -3.0   8   6
#4   1.0  15   8