鉴于分类数据的某些行,我想计算一个成对矩阵,其中包含这些行之间的差异数。
例如,将具有值[1, 0, 0, 1]
的行与具有值[0, 0, 1, 1]
的行进行比较,将得出结果值为2,因为索引0和2不同。
我想制作一个矩阵,显示每个成对组合的行。我为此编写了代码,但是在大数据上效率很低。我知道必须有一种更有效地执行此操作的方法,因为仅需要真正计算该矩阵的上半部分。
不过,我不知道如何将其转换为代码。这是我到目前为止的内容:
shortened = pd.DataFrame(
[{'c1':1, 'c2':0, 'c3':0}, {'c1':1,'c2':1, 'c3':0}, {'c1':0,'c2':0, 'c3':1}]
)
distm = [[""]+ list(shortened.index)]
found = {}
for index,row in shortened.iterrows():
newrow = [index]
for i2,r2 in shortened.iterrows():
if((i2,index) in found):
newrow.append(found[(i2,index)])
continue
if(index == i2):
newrow.append(0)
continue
summeddif = sum(i != j for i, j in zip(row, r2))
newrow.append(summeddif)
found[(index,i2)] = summeddif
distm.append(newrow)
因此,以此处的数据帧示例为例,可以获得正确的输出:
| 0 1 2
---------
0 | 0 1 2
1 | 1 0 3
2 | 2 3 0
但是,如果输入量很大,这将永远花费。是否有一种优雅的方法可以仅遍历上半部分,然后简单地复制到下半部分,因此我不需要进行不必要的比较?还是没有其他方法可以通过熊猫来改善这种状况?
答案 0 :(得分:2)
使用广播的异或。
(shortened.values ^ shortened.values[:, None]).sum(2)
array([[0, 1, 2],
[1, 0, 3],
[2, 3, 0]])
XOR是检查两个位是否相同的最简单(也是最快)的方法。只要您的输入是二进制,这应该就可以工作。
请注意,这会占用大量内存,尤其是对于非常大的帧,有机会在〜1M行出现OOM。