我有一个Pandas Dataframe ,我想把对角线设为0
import numpy
import pandas
df = pandas.DataFrame(numpy.random.rand(5,5))
df
Out[6]:
0 1 2 3 4
0 0.536596 0.674319 0.032815 0.908086 0.215334
1 0.735022 0.954506 0.889162 0.711610 0.415118
2 0.119985 0.979056 0.901891 0.687829 0.947549
3 0.186921 0.899178 0.296294 0.521104 0.638924
4 0.354053 0.060022 0.275224 0.635054 0.075738
5 rows × 5 columns
现在我想把对角线设为0:
for i in range(len(df.index)):
for j in range(len(df.columns)):
if i==j:
df.loc[i,j] = 0
df
Out[9]:
0 1 2 3 4
0 0.000000 0.674319 0.032815 0.908086 0.215334
1 0.735022 0.000000 0.889162 0.711610 0.415118
2 0.119985 0.979056 0.000000 0.687829 0.947549
3 0.186921 0.899178 0.296294 0.000000 0.638924
4 0.354053 0.060022 0.275224 0.635054 0.000000
5 rows × 5 columns
但肯定有比这更像Python的方式!?
8条答案
按热度按时间brgchamk1#
请注意,只有当
df
的行数和列数相同时,这种方法才有效。另一种适用于任意形状的方法是使用np.fill_diagonal:t2a7ltrp2#
使用
np.fill_diagonal(df.values, 1)
是最简单的,但是你需要确保你的列都有相同的数据类型,我有一个np.float64和python浮点的混合体,它只会影响numpy值。要解决这个问题,你必须把所有的东西都转换成numpy。owfi6suc3#
unutbu's answer中的两种方法都假设标签是不相关的(它们对底层值进行操作)。
OP代码使用
.loc
,所以是基于标签的(也就是说,在行-列中具有相同标签的单元格上放置0,而不是在位于对角线上的单元格上放置0--诚然,这在给定的特定示例中是无关紧要的,在该示例中,标签只是位置)。由于需要“基于标签”的对角填充(使用
DataFrame
描述不完整的邻接矩阵),我能想到的最简单的方法是:vhmi4jdf4#
这个解决方案是矢量化的,非常快,除非其他建议的解决方案适用于任何列名和df矩阵的大小。
507列和行的 Dataframe 的性能
1000圈,三局两胜:145 µs/循环
yshpjwxd5#
另一种实现方法是获得反单位矩阵,并将 Dataframe 与之相乘。
df * abs(np.eye(len(df))-1)
m528fe3b6#
这里有一个处理名词性恒等式的方法
输出:
dpiehjr47#
下面是一个对我有效的黑客:
o75abkj48#
所有依赖于修改
DataFrame.values
的答案都依赖于未记录的行为。values
属性被允许返回数据的副本,但是修改values
的解决方案假设它返回视图。有时它确实返回视图,但是panda文档没有保证它何时返回。