Pandas数据框,更改“对角线”上的值(其中索引值等于列名)

4
我有一个pandas DataFrame,其中索引是列的子集,即索引中的每个值也是一列名称,并且还有其他列,类似于这样:
import pandas as pd
import numpy as np
df = pd.DataFrame(index=['John', 'Mary', 'Steven'],
                  columns=['John','Susan','Steven','Chris','Mary'],
                  data=np.arange(15).reshape(3,5))

我现在想将“对角线”项设置为一个固定值,比如0.0。所谓的“对角线”是指索引值与列名匹配的那些条目。我可以通过迭代索引并在该循环内将每个“对角线”条目设置为0.0来实现。
for i in df.index:
    df.loc[i, i] = 0.0

但是我想知道是否有更符合Python风格的方法,即可能实现这一点的向量化方法。我想必须有类似于df.loc[df.index, df.index] = 0.0的东西,但它并不产生所需的结果。

1
我认为你的做法可能是最好的。我不确定“向量化”在你的情况下是否有任何实际意义。在你获得速度的程度上,我认为你必须已经拥有一个行和列顺序相同的正方形数据框架。鉴于这两个条件都不适用于此,我不认为有理由改变你现有的做法。 - JohnE
1个回答

6
您可以使用NumPy的fill_diagonal函数。
import numpy as np 

#rearrange columns according to order of index
df = df.reindex(columns=list(df.index) + list(df.columns.difference(df.index))) 

np.fill_diagonal(df.values,0)

print df
         John  Mary  Steven  Chris  Susan
John       0     4       2      3      1
Mary       5     0       7      8      6
Steven    10    14       0     13     11

遗憾的是,顺序是任意的(如我的示例所示)。在您的示例中,它会产生错误的结果,即对于玛丽,对角线未设置为0。 - Nras
我明白了。按照索引的顺序重新排列列,然后调用fill_diagonal函数怎么样? - Ankush Shah
还不太正确,但已经接近了。你正在更改列,但需要重新索引(否则会更改数据)。我想“df = df.reindex(columns=list(df.index) + list(df.columns - df.index))”可能有效。我明天会检查一下。 - Nras
我认为,我们现在已经得到了一个可行的解决方案,尽管我对这是否比我最初提出的循环更快或更慢持怀疑态度,但我仍然会尝试一下! - Nras
@Nras:根据您最后的编辑(取并集而不是转换为列表),顺序将会丢失。 - Ankush Shah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接