以下代码允许我查找匹配值:
var a = function (callback) {
for (var eachRow = 0; eachRow < 20; eachRow++) {
for (var eachCol = 0; eachCol < 20; eachCol++) {
callback(array, eachRow, eachCol);
}
}
};
a(function (array, x, y) {
if (array[x][y]){
//do something
}
});
有关此内容的信息可以在here找到:
更好的解释来自@Andras Deak
“from itertools import combinations
df = pd.DataFrame(np.random.randn(12, 3), columns=['A', 'B', 'C'])
thresh = .3
df['matches'] = sum(abs(df[k1]-df[k2])<thresh for k1,k2 in combinations(df.keys(),2))
中的生成器表达式遍历每个列对,并构造相应的布尔向量。这些对每个列对求和,并将结果列附加到数据帧”。
thresh = 0.3的示例输出:
sum()
如何返回另一列 A B C matches
0 0.146360 -0.099707 0.633632 1
1 1.462810 -0.186317 -1.411988 0
2 0.358827 -0.758619 0.038329 0
3 0.077122 -0.213856 -0.619768 1
4 0.215555 1.930888 -0.488517 0
5 -0.946557 -0.904743 -0.004738 1
6 -0.080209 -0.850830 -0.866865 1
7 -0.997710 -0.580679 -2.231168 0
8 1.762313 -0.356464 -1.813028 0
9 1.151338 0.347636 -1.323791 0
10 0.248432 1.265484 0.048484 1
11 0.559934 -0.401059 0.863616 0
,提供匹配值的平均值?因此,对于上面示例中的第一行,它将返回df['matches_mean']
&amp;的平均值。 0.146360
。我希望这使用与原始代码相同的-0.099707
逻辑,因为这可以很好地扩展到我的实际数据。
答案 0 :(得分:1)
暂时在这里是一个几乎完美的解决方案。问题是,当您想要计算多个匹配的平均值时(例如,一行中的所有三个数字都接近阈值),您需要在计算均值时采用适当数量的值。如果3列中只有1或3个匹配,则很容易。但是当两对数字“接近”但第三对不是时,下面的代码会出错。
我们的想法是总结每行和每个组合的匹配值。如果只有行'A'
和'B'
“关闭”(在阈值内),我们会得到df.A+df.B
,必须将其除以2才能获得均值。当所有三个都“接近”时,我们得到2*df.A + 2*df.B + 2*df.C
,可以除以6以获得正确的均值。但是,在第三种情况下,我们得到df.A + 2*df.B + df.C
(当A和B接近时,B和C接近,但A和C不接近)。在这种情况下,我们不能除以任何东西来获得正确的意思。我们应该将4除以得到“大致一个”元素的错误均值。我的观点是,如果我们要妥善处理这种情况,代码将会复杂得多,并且根据您的需要,它可能不值得。目前还不清楚你究竟想要处理这种情况。将上述除以4的当前版本相当于平均A与B,平均B与C,然后再次平均这些平均值。
所以这里是:
import numpy as np
import pandas as pd
from itertools import combinations
colnames = ['A', 'B', 'C']
df = pd.DataFrame(np.random.randn(12, 3), columns=colnames)
thresh = .3
df['matches'] = sum(abs(df[k1]-df[k2])<thresh
for k1,k2 in combinations(colnames,2))
# this is your starting point, we'll need df['matches'] too
tmpsums = sum(np.where(abs(df[k1]-df[k2])<thresh,df[k1]+df[k2],0)
for k1,k2 in combinations(colnames,2))
# divide by 2/4/6:
df['matches_mean'] = np.where(df['matches'],tmpsums/df['matches']/2,0)
我承认,出现在生成器表达上的总和达到了良好品味的极限。你可能想要在适当的for循环中写出来,但是你必须逐步总结tmpsums
中的值。我承认这可能更漂亮。
无论如何,这个第二个生成器表达式的工作方式与第一个类似。产值当然不同,它是
np.where(abs(df[k1]-df[k2])<thresh,df[k1]+df[k2],0)
也就是说,如果这些值比thresh更接近,它将给出给定列对的元素的总和,否则我们得到0.对于所有3个组合,我们得到一个具有零或两个和的数组-elements值,我们再次总结。如果有0个匹配,我们得到0.如果有1个匹配,我们总结了两个匹配元素。对于2场比赛,我们得到前面提到的混合总和,如果有3场比赛,我们会有两次所有术语。
剩下的就是将非零个案除以匹配数,这只是我们已经知道的两次匹配的除法(但我们必须注意除零)。
带thresh = 0.3
的示例输出:
A B C matches matches_mean
0 0.716278 0.681279 0.861410 3 0.752989
1 -0.109029 -0.646952 0.268038 0 0.000000
2 -1.095221 -1.088397 1.100645 1 -1.091809
3 -1.970372 -0.367096 -0.337098 1 -0.352097
4 -1.030003 0.082001 -0.807431 1 -0.918717
5 1.660611 -0.046429 0.557107 0 0.000000
6 -0.508715 -0.588217 0.014917 1 -0.548466
7 0.578028 -0.187097 -0.420243 1 -0.303670
8 0.233687 1.311917 1.888947 0 0.000000
9 0.478863 1.087957 -0.897025 0 0.000000
10 -0.001462 0.866320 -1.198642 0 0.000000
11 0.297946 0.564325 -1.098887 1 0.431135