我有以下名为df:的DataFrame
数字 | 国家1 | 国家2国家3 | >国家4国家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)
...