暂时这里是一个几乎完美的解决方案。问题是,当你想计算多个匹配的平均值(比如说,一行中的所有三个数字都接近阈值)时,你需要在计算平均值时取适当数量的值。如果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)
也就是说,它会给我们给定的列对,如果这些值比脱粒接近的元素的总和,否则我们得到0。对于所有3组合我们得到一个具有这样的零或者两个和的元素值的数组,并且我们再次总结它们。在有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
如果多于一对列的接近什么?该专栏应包含哪些内容? –
你好安德拉斯。我最终寻找大多数比赛以及这场比赛的平均数。所以如果3列匹配并且2匹配来自同一行,那么3列的平均值将是理想的。谢谢你的帮助! – ade1e
那么没有匹配的行呢? –