我有一个数据框架,
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