Как сравнить каждую ячейку в одном столбце с указанным значением c в pandas? - PullRequest
2 голосов
/ 23 января 2020

У меня есть такой фрейм данных, я хочу добиться этого:

, если знак A совпадает со знаком B, получить новый столбец C = min (3, | A |); если знак A отличается от знака B, C = min (3, B); если значения A и B равны нулю, C = A

Type subType  A       B     C     
 X    a       -1      4     3   
 X    a       5       9     3
 X    a       5       9     3
 X    b       1       4     1   
 X    b       3       5    ...
 X    b       5       0
 Y    a       -1      1         
 Y    a       3       2  
 Y    a       -5      3
 Y    b       1       4        
 Y    b       3       5 
 Y    b       5      -2

Я попытался:

if df["A"] * df["B"] > 0:
    df["C"] = (3, abs(df["A"]).min(axis=1)

Это дало мне ошибку, похоже, я не могу сравнить значение '3 'с колонкой напрямую, какие-либо предложения?

Продолжение: что, если формула более сложная, как C = A + min(3, |A|) *B?

Ответы [ 4 ]

4 голосов
/ 23 января 2020

Поскольку, если значения для A & B равны нулю, это означает использование минимума между (3, abs (0)), что всегда 0 решение должно быть упрощено с numpy.where и numpy.minimum:

#compare signs
m = np.sign(df["A"]) == np.sign(df["B"])
#alternative
#m = (df["A"] * df["B"]) >= 0
df['C'] = np.where(m, np.minimum(3, df.A.abs()), np.minimum(3, df.B))
print (df)
   Type subType  A  B  C
0     X       a -1  4  3
1     X       a  5  9  3
2     X       a  5  9  3
3     X       b  1  4  1
4     X       b  3  5  3
5     X       b  5  0  0
6     Y       a -1  1  1
7     Y       a  3  2  3
8     Y       a -5  3  3
9     Y       b  1  4  1
10    Y       b  3  5  3
11    Y       b  5 -2 -2

РЕДАКТИРОВАТЬ: Если нужно больше условий в пандах / numpy возможно использовать вместо нескольких np.where функция numpy.select:

m1 = np.sign(df.A) == np.sign(df.B)
m2 = np.sign(df.A) == np.sign(df.C)

s1 = df.A + np.minimum(3, df.A.abs()) * df.B
s2 = df.C + np.minimum(3, df.A.abs()) * df.B

df['D'] = np.select([m1, m2], [s1, s2], default=df.A)
print (df)
   Type subType  A  B  C   D
0     X       a -1  4  3  -1
1     X       a  5  9  3  32
2     X       a  5  9  3  32
3     X       b  1  4  1   5
4     X       b  3  5  3  18
5     X       b  5  0  0   5
6     Y       a -1  1  1  -1
7     Y       a  3  2  3   9
8     Y       a -5  3  3  -5
9     Y       b  1  4  1   5
10    Y       b  3  5  3  18
11    Y       b  5 -2 -2   5
0 голосов
/ 23 января 2020

Вы можете попробовать это так:

df["C"] = np.where(df["A"]*df["B"]>0, min(3,abs(df["A"]).min()),
                   np.where(df["A"]*df["B"]<0, min(3,df["B"].min()),
                            df["A"]))

df
   Type subType  A  B  C
0     X       a -1  4 -2
1     X       a  5  9  1
2     X       a  5  9  1
3     X       b  1  4  1
4     X       b  3  5  1
5     X       b  5  0  5
6     Y       a -1  1 -2
7     Y       a  3  2  1
8     Y       a -5  3 -2
9     Y       b  1  4  1
10    Y       b  3  5  1
11    Y       b  5 -2 -2
0 голосов
/ 23 января 2020
df['C'] = np.where(df.A.mul(df.B).gt(0), df.A.abs().clip(upper=3), 
                   np.where(df.A.mul(df.B).lt(0), df.B.clip(upper=3), df.A)
                  )


    Type    subType A   B   C
0   X       a       -1  4   3
1   X       a       5   9   3
2   X       a       5   9   3
3   X       b       1   4   1
4   X       b       3   5   3
5   X       b       5   0   5
6   Y       a      -1   1   1
7   Y       a       3   2   3
8   Y       a      -5   3   3
9   Y       b       1   4   1
10  Y       b       3   5   3
11  Y       b       5  -2  -2
0 голосов
/ 23 января 2020
df['C'] = [min(abs(a), 3) if a*b > 0 else min(b, 3) if a*b < 0 else a for a,b in zip(df.A, df.B)]
...