Pandas np.where在行上具有匹配的值范围

时间:2016-12-15 21:15:27

标签: python pandas

测试数据:

In [1]:
import pandas as pd
import numpy as np
df = pd.DataFrame(
       {'AAA' : [4,5,6,7,9,10], 
        'BBB' : [10,20,30,40,11,10],
        'CCC' : [100,50,25,10,10,11]});
In [2]:df
Out[2]:
   AAA  BBB  CCC
0    4   10  100
1    5   20   50
2    6   30   25
3    7   40   10
4    9   11   10
5   10   10   11

In [3]: thresh = 2
        df['aligned'] = np.where(df.AAA == df.BBB,max(df.AAA)|(df.BBB),np.nan)

np.wheremax(df.AAA or df.BBB)完全一致时,以下df.AAA语句会提供df.BBB。当列在max中的值内时,我希望thresh并考虑所有列。它不一定是通过np.where。你能告诉我接近这个的方法吗?

因此,对于第5行,11.0中的df.aligned应为thresh,因为这是df.AAA df.BBBdf AAA BBB CCC aligned 0 4 10 100 NaN 1 5 20 50 NaN 2 6 30 25 NaN 3 7 40 10 NaN 4 9 11 10 NaN 5 10 10 11 10.0 的最大值。

最终,我正在寻找在多个列中找到水平紧密对齐的水平的方法。

我的代码的当前输出:

df
   AAA  BBB CCC aligned
0   4   10  100 NaN
1   5   20  50  NaN
2   6   30  25  NaN
3   7   40  10  NaN
4   9   11  10  11.0
5   10  10  11  11.0

期望输出:

df.aligned

所需的输出显示第4行和第5行,其值为thresh。因为它们的值在thresh之内(值10和11在{{变量中指定的范围内)。

1 个答案:

答案 0 :(得分:3)

“在阈值距离内”对我来说意味着max之间的差异  并且行的min应小于thresh。我们可以将DataFrame.apply与参数axis=1一起使用,以便我们在每个上应用lambda函数。

In [1]: filt_thresh = df.apply(lambda x: (x.max() - x.min())<thresh, axis=1)
100 loops, best of 3: 1.89 ms per loop

另外,如@root所指出的更快的解决方案:

filt_thresh = np.ptp(df.values, axis=1) < tresh
10000 loops, best of 3: 48.9 µs per loop

或者,留在熊猫:

filt_thresh = df.max(axis=1) - df.min(axis=1) < thresh
1000 loops, best of 3: 943 µs per loop

我们现在可以使用boolean indexing并计算匹配的每一行的最大值(因此再次axis=1中的max()参数):

In [2]:  df.loc[filt_thresh, 'aligned'] = df[filt_thresh].max(axis=1)

In [3]: df
Out[3]: 
   AAA  BBB  CCC  aligned
0    4   10  100      NaN
1    5   20   50      NaN
2    6   30   25      NaN
3    7   40   10      NaN
4    9   11   10      NaN
5   10   10   11     11.0

更新

如果你想计算每一行元素之间的最小距离,这相当于排序值数组(np.sort()),计算连续数字之间的差异(np.diff),并获取结果数组的min。最后,将其与tresh进行比较。

这是apply方式,具有更清晰易懂的优势。

filt_thresh = df.apply(lambda row: np.min(np.diff(np.sort(row))) < thresh, axis=1)

1000 loops, best of 3: 713 µs per loop

这是矢量化的等价物:

filt_thresh = np.diff(np.sort(df)).min(axis=1) < thresh

The slowest run took 4.31 times longer than the fastest. 
This could mean that an intermediate result is being cached.
10000 loops, best of 3: 67.3 µs per loop