我正在尝试确定DataFrame
的一行中的给定值是否在单独的DataFrame
的另外两列内,或者该估计值是否为零。
import pandas as pd
df = pd.DataFrame([[-1, 2, 1, 3], [4, 6, 7,8], [-2, 10, 11, 13], [5, 6, 8, 9]],
columns=['lo1', 'up1','lo2', 'up2'])
lo1 up1 lo2 up2
0 -1 2 1 3
1 4 6 7 8
2 -2 10 11 13
3 5 6 8 9
df2 = pd.DataFrame([[1, 3], [4, 6] , [5, 8], [10, 2,]],
columns=['pe1', 'pe2'])
pe1 pe2
0 1 3
1 4 6
2 5 8
3 10 2
更清楚地说,是否可以开发一个for
-循环或使用一个函数,该函数可以查看pe1
及其相应的值,并确定它们是否在lo1
和up1
内,lo1
和up1
是否过零,以及pe1=0
是否过零?我很难用Python编写这个代码。
编辑:我希望输出类似于:
m1 m2
0 0 3
1 4 0
2 0 0
3 0 0
由于落在其对应的lo
和up
列内的唯一pe
在第一行第二列和第二行第一列中。
您最终可以沿着横轴连接两个数据帧,然后使用np.where
。这与RJ Adriaansen使用的where
具有类似的行为。
import pandas as pd
import numpy as np
# Data
df1 = pd.DataFrame([[-1, 2, 1, 3], [4, 6, 7,8], [-2, 10, 11, 13], [5, 6, 8, 9]],
columns=['lo1', 'up1','lo2', 'up2'])
df2 = pd.DataFrame([[1, 3], [4, 6] , [5, 8], [10, 2,]],
columns=['pe1', 'pe2'])
# concatenate dfs
df = pd.concat([df1, df2], axis=1)
现在df
看起来像
lo1 up1 lo2 up2 pe1 pe2
0 -1 2 1 3 1 3
1 4 6 7 8 4 6
2 -2 10 11 13 5 8
3 5 6 8 9 10 2
最后我们使用np.where
和between
for k in [1, 2]:
df[f"m{k}"] = np.where(
(df[f"pe{k}"].between(df[f"lo{k}"], df[f"up{k}"]) &
df[f"lo{k}"].gt(0)),
df[f"pe{k}"],
0)
结果是
lo1 up1 lo2 up2 pe1 pe2 m1 m2
0 -1 2 1 3 1 3 0 3
1 4 6 7 8 4 6 4 0
2 -2 10 11 13 5 8 0 0
3 5 6 8 9 10 2 0 0
您可以为所需条件创建布尔掩码。对于pe1
,这将是:
lo1
中的- 值小于或等于
pe1
up1
中的值大于或等于pe1
lo1
中的值大于0
这将使这个掩码:
(df['lo1'] <= df2['pe1']) & (df['up1'] >= df2['pe1']) & (df['lo1'] > 0)
返回:
0 False
1 True
2 False
3 False
dtype: bool
现在,您可以使用where来保留与True
匹配的值,并将不匹配的值替换为0
:
df2['pe1'] = df2['pe1'].where((df['lo1'] <= df2['pe1']) & (df['up1'] >= df2['pe1']) & (df['lo1'] > 0), other=0)
df2['pe2'] = df2['pe2'].where((df['lo2'] <= df2['pe2']) & (df['up2'] >= df2['pe2']) & (df['lo2'] > 0), other=0)
结果:
0 | 1 | 4 | 0 | |
2 | 3 |