【问题标题】:np.where with multiple conditionsnp.where 有多个条件
【发布时间】:2020-04-02 22:42:26
【问题描述】:

我有以下示例数据框。

     A    B    C    D
1     0    0    0
2     0    0    1
3     1    1    0
4     0    0    1
5    -1    1    1
6     0    0    1
7     0    1    0
8     1    1    1
9     0    0    0
10   -1    0    0

我需要根据以下规则填写 D 列。

1) 我手动将 D 的第一个值赋值为 0

       df.loc[[0], 'D'] = 0

2) 我需要根据以下条件填充 df['D'] 的其余行。

   IF 
        A = 1 AND B = 1 AND D.SHIFT(1) = 0, THEN D = 1
   ELSE IF 
        A = 0, THEN D = D.SHIFT(1)
   ELSE IF 
        A = -1 AND C = 1 AND D.SHIFT(1) = 0, THEN D = -1
   ELSE
        D = 0

以下是我的代码。

import numpy as np
import pandas as pd

df = pd.DataFrame([[0, 0, 0]]*10, columns=list('ABC'), index=range(1, 11))
df.loc[[3, 8], 'A'] = 1
df.loc[[5, 10], 'A'] = -1
df.loc[[3, 5, 7, 8], 'B'] = 1
df.loc[[2, 4, 5, 6, 8], 'C'] = 1
df.loc[[1], 'D'] = 0
df['D'] = np.where((df.A == 1) & (df.B == 1) & (df.D.shift(1) == 0), 1, 
               np.where((df.A == 0) , df.D.shift(1), 
               np.where((df.A == -1) & (df.C == 1) & (df.D.shift(1) == 0), -1, 0)))

print(df)

预期的输出是

   A  B  C    D
1   0  0  0  0
2   0  0  1  0
3   1  1  0  1
4   0  0  1  1
5  -1  1  1  0
6   0  0  1  0
7   0  1  0  0
8   1  1  1  1
9   0  0  0  1
10 -1  0  0  0

但我收到的实际输出如下,这不是我想要的输出。

    A  B  C    D
1   0  0  0  NaN
2   0  0  1  0.0
3   1  1  0  0.0
4   0  0  1  NaN
5  -1  1  1  0.0
6   0  0  1  NaN
7   0  1  0  NaN
8   1  1  1  0.0
9   0  0  0  NaN
10 -1  0  0  0.0

我真的很感激这里的任何帮助。

编辑:我分配 df['D'] = 0 的第一行的原因是,df['D'] 也取决于 df['D'].shift(1)。如果即使没有分配 df['D'] 的第一个值,还有其他方法可以做到这一点,我也可以。

【问题讨论】:

  • 那是np.select
  • @QuangHoang 恕我直言,事实并非如此。因为请求根据前一个值(第 n-1 行)搜索第 n 行中的值。
  • 为了满足两个条件,您可以使用 np.logical_and(df.loc[row, 'A'] == 1, df.loc[row, 'B'] == 1) 例如,但看起来您想动态生成 D 的值,因此您需要使用 @987654329 遍历行@这样你就可以shiftD栏目了。
  • 叫我疯了,但我认为在这种情况下apply 可能是最好的方法。
  • 第二个(或第三个)循环解决方案。

标签: python pandas numpy multiple-conditions


【解决方案1】:

定义如下函数:

def fn(row):
    if fn.prevD is None:
        fn.prevD = 0
    elif (row.A == 1) & (row.B == 1) & (fn.prevD == 0):
        fn.prevD = 1
    elif row.A == 0:
        pass
    elif (row.A == -1) & (row.C == 1) & (fn.prevD == 0):
        fn.prevD = -1
    else:
        fn.prevD = 0
    return fn.prevD

然后应用它:

fn.prevD = None
df['D'] = df.apply(fn, axis=1)

【讨论】:

    猜你喜欢
    • 2022-06-13
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    • 1970-01-01
    • 2017-11-18
    • 1970-01-01
    • 2016-08-04
    • 2022-12-02
    相关资源
    最近更新 更多