如何将一列中的每个单元格与 pandas 中的特定值进行比较?
How to compare each cell in one column with a specific value in pandas?
我有一个这样的数据框,我想实现这个:
如果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
怎么办?
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)]
因为如果 A 和 B 的值为零,则意味着在 (3, abs(0)) 之间使用最小值,始终 0
解决方案应简化为 numpy.where
and 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
编辑:如果在 pandas/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
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
您可以像这样尝试:
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
我有一个这样的数据框,我想实现这个:
如果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
怎么办?
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)]
因为如果 A 和 B 的值为零,则意味着在 (3, abs(0)) 之间使用最小值,始终 0
解决方案应简化为 numpy.where
and 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
编辑:如果在 pandas/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
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
您可以像这样尝试:
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