如何创建一个取三列之和的函数,但每次迭代后一列都会发生变化



我有以下名为df:的DataFrame

国家2>国家4否是是是否否否是是否
数字 国家1国家3国家5
5 否是
10
6是
8是
9

这可以通过用Yes屏蔽列来完成,然后使用np.einsum为每行两列的每个组合获取True或False。乘以数值列中的值和代表行的轴上的sum(在我选择的einsum中的下标中,它是最后一个(。根据需要创建一个具有索引和列的数据帧

m = df.drop(['Numeric'], axis=1).eq('Yes')
print(m)
#    Country1  Country2  Country3  Country4  Country5
# 0      True     False     False      True      True
# 1     False      True      True     False      True
# 2      True     False     False      True     False
# 3      True     False      True      True      True
# 4     False      True     False      True     False
res = pd.DataFrame(
data=(np.einsum('ij,ik->jki',m,m)
*df['Numeric'].to_numpy()[None,:]
).sum(axis=-1),
index=m.columns, 
columns = m.columns
)
print(res)
#           Country1  Country2  Country3  Country4  Country5
# Country1        19         0         8        19        13
# Country2         0        19        10         9        10
# Country3         8        10        18         8        18
# Country4        19         9         8        28        13
# Country5        13        10        18        13        23

注意:您甚至可以执行data = np.einsum('ij,ik,i->jk',m,m,df['Numeric'].to_numpy()),它包括与数字列的乘积和直接在最后一个轴上的和。

EDIT:这里有一种使用combinations_with_replacement的方法,它可能更容易理解正在发生的事情(但einsum的原始答案执行相同风格的操作(。

from itertools import combinations_with_replacement
#split mask and values
m = df.drop(['Numeric'], axis=1).eq('Yes')
arr = df['Numeric'].to_numpy()
# create result dataframe
res = pd.DataFrame(data=0, index=m.columns, columns=m.columns)
# fill each cell
for colA, colB in combinations_with_replacement(m.columns, 2):
res.loc[colA, colB] = res.loc[colB, colA] = ((m[colA]&m[colB])*arr).sum()
print(res)
# same result

这里有一种方法:

from itertools import product
country_cols = [c for c in df.columns if c.startswith("Country")]
df1 = pd.DataFrame(None, index=country_cols, columns=country_cols)
combs = product(country_cols, country_cols)
for comb in combs:
matches = (df[list(comb)] == 'Yes').all(axis=1)
total = df.loc[matches, 'Numeric'].sum()
df1.loc[comb[0], comb[1]] = total
print(df1)

输出:

Country1 Country2 Country3 Country4 Country5
Country1       19        0        8       19       13
Country2        0       19       10        9       10
Country3        8       10       18        8       18
Country4       19        9        8       28       13
Country5       13       10       18       13       23

这是你想要的吗?

注意,得到的矩阵是对称的。如果您乐于只计算唯一的结果(无重复(,请使用:

from itertools import combinations
combs = combinations(country_cols, 2)
...

相关内容

最新更新