Python 数据帧填充单元格中的 1,具有行和列的包含关系



我有一个数据框架,

L-1    L-1-1   L-1-2   L-1-3   L-2     L-2-1   L-2-2   L-2-3
L-1    0        0       0       0     0         0       0       0
L-1-1  0        0       0       0     0         0       0       0
L-1-2  0        0       0       0     0         0       0       0
L-1-3  0        0       0       0     0         0       0       0
L-2    0        0       0       0     0         0       0       0
L-2-1  0        0       0       0     0         0       0       0
L-2-2  0        0       0       0     0         0       0       0
L-2-3  0        0       0       0     0         0       0       0

我想在每个单元格中填充包含行和列关系的1

输出将是

L-1    L-1-1   L-1-2   L-1-3   L-2     L-2-1   L-2-2   L-2-3
L-1    1        1       1       1     0         0       0       0
L-1-1  0        1       0       0     0         0       0       0
L-1-2  0        0       1       0     0         0       0       0
L-1-3  0        0       0       1     0         0       0       0
L-2    0        0       0       0     1         1       1       1
L-2-1  0        0       0       0     0         1       0       0
L-2-2  0        0       0       0     0         0       1       0
L-2-3  0        0       0       0     0         0       0       1

例如,

字符串"L-1"包括"L-1"所以单元格(1,1)就是1

字符串"L1-1-1"包括"L-1"所以单元格(1,2)就是1

字符串" l - 2-1-1 "不包括"l -1";因此单元格(1,6)将为0。

等等

使用numpy广播来比较原始索引和列,以及在最后一个_之后删除值的列,然后传递给DataFrame.mask:

i1 = df.index.to_numpy()
c1 = df.columns.to_numpy()
c = df.columns.str.rsplit('-', n=1).str[0].to_numpy()
df = df.mask((c == i1[:, None]) | (c1 ==  i1[:, None]), 1)
print (df)
L-1  L-1-1  L-1-2  L-1-3  L-2  L-2-1  L-2-2  L-2-3
L-1      1      1      1      1    0      0      0      0
L-1-1    0      1      0      0    0      0      0      0
L-1-2    0      0      1      0    0      0      0      0
L-1-3    0      0      0      1    0      0      0      0
L-2      0      0      0      0    1      1      1      1
L-2-1    0      0      0      0    0      1      0      0
L-2-2    0      0      0      0    0      0      1      0
L-2-3    0      0      0      0    0      0      0      1

或者对掩码的每个索引值使用Series.str.startswith:

df = df.mask(np.array(list(df.index.map(lambda x: df.columns.str.startswith(x)))), 1)
print (df)
L-1  L-1-1  L-1-2  L-1-3  L-2  L-2-1  L-2-2  L-2-3
L-1      1      1      1      1    0      0      0      0
L-1-1    0      1      0      0    0      0      0      0
L-1-2    0      0      1      0    0      0      0      0
L-1-3    0      0      0      1    0      0      0      0
L-2      0      0      0      0    1      1      1      1
L-2-1    0      0      0      0    0      1      0      0
L-2-2    0      0      0      0    0      0      1      0
L-2-3    0      0      0      0    0      0      0      1

最新更新