想象一下,如果“组合”以以下格式(或类似格式)存储在文件中:
A,B,1
A,C,0
A,D,1
B,C,1
B,D,1
C,D,0
那么你可以这样做:
df = pd.read_csv(filename, header=None)
示例(使用您的示例数据):
txt = """A,B,1
A,C,0
A,D,1
B,C,1
B,D,1
C,D,0
"""
df = pd.read_csv(io.StringIO(txt), header=None)
现在df 包含:
0 1 2
0 A B 1
1 A C 0
2 A D 1
3 B C 1
4 B D 1
5 C D 0
从那时起,一点点按摩就会得到你想要的:
# all labels (for rows and cols)
r = sorted(set(df[0]) | set(df[1]))
# upper triangular
z = (
df.set_index([0, 1])
.reindex(pd.MultiIndex.from_product([r, r]))
.squeeze()
.unstack(1)
)
# fill in the lower triangular part to make z symmetric
z = z.where(~z.isna(), z.T)
我们得到:
>>> z
A B C D
A NaN 1.0 0.0 1.0
B 1.0 NaN 1.0 1.0
C 0.0 1.0 NaN 0.0
D 1.0 1.0 0.0 NaN
注意:如果您更喜欢留在int-only(并将对角线设置为 0),那么:
z = (
df.set_index([0, 1])
.reindex(pd.MultiIndex.from_product([r, r]), fill_value=0)
.squeeze()
.unstack(1)
)
z += z.T
现在:
>>> z
A B C D
A 0 1 0 1
B 1 0 1 1
C 0 1 0 0
D 1 1 0 0
为了速度
现在,如果您确定您正在处理 4x4 矩阵并且顺序与您指示的完全一致(按上三角形排序),您可以执行以下操作以加快设置:
# get the triangular values, somehow (e.g. read file and discard
# all but the last value;
# here we simply take them from the df above:
tri = df[2].values # np.array([1, 0, 1, 1, 1, 0])
# and now, in pure numpy:
z = np.zeros((4,4), dtype=int)
z[np.triu_indices(4, 1)] = tri
z += z.T
结果是一个简单的numpy 数组(无标签):
>>> z
[[0 1 0 1]
[1 0 1 1]
[0 1 0 0]
[1 1 0 0]]