我正在尝试解决这个问题:
有一个带有两列实数的 DataFrame。
我想构建第三列,它将采用值:
- 1 - 如果第二列中的数字大于第一列中的数字
- 0 - 如果两列中的数字相等
- -1 - 如果第二列中的数字小于第一列中的数字
比较时,我想考虑一些 epsilon,因为 由于测量误差,这些数字可能“大致相等”。
我写了这段代码,它似乎可以按我的需要工作:
columns = ['col1', 'col2']
data = [[1.0, 1.0], [1.0, 2.0], [2.0, 1.0]]
epsilon = 0.01
df = pd.DataFrame(data, columns=columns)
df['is_up'] = np.where((df['col2'] - df['col1'] > epsilon),1, np.nan)
df['is_down'] = np.where((df['col2'] - df['col1'] < - epsilon),-1, np.nan)
df['is_equal'] = np.where((abs(df['col2'] - df['col1']) < epsilon),0, np.nan)
df['col3'] = df[['is_up','is_down','is_equal']].replace('None','').sum(1)
结果:
-----------------------------------------------
col1 | col2 | is_up | is_down | is_equal | col3
-----------------------------------------------
1.0 |1.0 |NaN |NaN |0.0 |0.0
1.0 |2.0 |1.0 |NaN |NaN |1.0
2.0 |1.0 |NaN |-1.0 |NaN |-1.0
但是,我有一种感觉,它可以做得更简单,更清晰,更快。请指出正确的道路!
在我看来,我可以提供一个更易于理解的解决方案,但使用额外的 numba 库。这个库中的 vectorize 装饰器允许您使用值的向量(数组),就好像它们是普通数字一样(并且做得非常快)。
原则上,如果您在传递给函数输入的数组值的循环中进行并行迭代,则可以不使用向量化,但是使用这样的装饰器,代码更清晰,应该可以很快工作.
np.isclose()也可以使用np.sign():