测试数据:
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.where
和max(df.AAA or df.BBB)
完全一致时,以下df.AAA
语句会提供df.BBB
。当列在max
中的值内时,我希望thresh
并考虑所有列。它不一定是通过np.where
。你能告诉我接近这个的方法吗?
因此,对于第5行,11.0
中的df.aligned
应为thresh
,因为这是df.AAA
df.BBB
和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 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在{{
变量中指定的范围内)。
答案 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