我生成了一个matplotlib 3d曲面图。我只需要在图上看到矩阵的上三角形一半,因为另一半是多余的。
np.triu()使矩阵的多余半部分为零,但我更喜欢如果我能使它们为Nans,那么这些细胞根本不会出现在曲面图上。
用NaN代替零填充的pythonic方法是什么?我无法使用NaN进行搜索和替换0,因为零将显示在我想要显示的合法数据中。
答案 0 :(得分:9)
您可以使用numpy.tril_indices()
将NaN
值分配给较低的三角形,例如:
>>> import numpy as np
>>> m = np.triu(np.arange(0, 12, dtype=np.float).reshape(4,3))
>>> m
array([[ 0., 1., 2.],
[ 0., 4., 5.],
[ 0., 0., 8.],
[ 0., 0., 0.]])
>>> m[np.tril_indices(m.shape[0], -1)] = np.nan
>>> m
array([[ 0., 1., 2.],
[ nan, 4., 5.],
[ nan, nan, 8.],
[ nan, nan, nan]])
答案 1 :(得分:1)
tril_indices()
可能是生成较低三角形索引的明显方法,然后您可以使用它们将输入数组中的那些设置为<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="200dp"
android:id="@+id/cv"
android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"
card_view:cardCornerRadius="6dp"
card_view:cardUseCompatPadding="true"
card_view:cardElevation="2dp">
<!-- compat padding is required if using AppCompat -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp" >
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/thumbnail"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginRight="16dp"
android:src="@drawable/india"
android:scaleType="centerCrop" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/firstLine"
android:layout_toRightOf="@+id/thumbnail"
android:layout_alignParentTop="false"
android:textSize="20sp"
android:text="Tennis with Peter"
android:layout_alignTop="@+id/thumbnail" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/secondLine"
android:layout_below="@+id/firstLine"
android:text="10 Oct at 7pm"
android:layout_alignLeft="@+id/firstLine" />
<Button
android:layout_width="180dp"
android:layout_height="wrap_content"
android:text="YES"
android:id="@+id/button3"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignLeft="@+id/thumbnail" />
<Button
android:layout_width="60dp"
android:layout_height="wrap_content"
android:text="NO"
android:id="@+id/button4"
android:layout_toRightOf="@+id/button3"
android:layout_alignBottom="@+id/button3"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="false" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
。
现在,如果您关心性能,可以在创建这种较低三角形的蒙版之后使用boolean indexing
,然后将其设置为NaNs
。实现看起来像这样 -
NaNs
因此,m[np.arange(m.shape[0])[:,None] > np.arange(m.shape[1])] = np.nan
是使用broadcasting
创建的掩码。
示例运行 -
np.arange(m.shape[0])[:,None] > np.arange(m.shape[1])
运行时测试 -
本节将此解决方案中列出的基于布尔索引的方法与基于other solution
的基于In [51]: m
Out[51]:
array([[ 11., 49., 23., 30.],
[ 40., 41., 19., 26.],
[ 32., 36., 30., 25.],
[ 15., 27., 25., 40.],
[ 33., 18., 45., 43.]])
In [52]: np.arange(m.shape[0])[:,None] > np.arange(m.shape[1]) # mask
Out[52]:
array([[False, False, False, False],
[ True, False, False, False],
[ True, True, False, False],
[ True, True, True, False],
[ True, True, True, True]], dtype=bool)
In [53]: m[np.arange(m.shape[0])[:,None] > np.arange(m.shape[1])] = np.nan
In [54]: m
Out[54]:
array([[ 11., 49., 23., 30.],
[ nan, 41., 19., 26.],
[ nan, nan, 30., 25.],
[ nan, nan, nan, 40.],
[ nan, nan, nan, nan]])
的方法进行比较。
np.tril_indices
答案 2 :(得分:-1)
为了这个例子的目的,形状或布局并不重要,所以我们假设我们有一个2D数组,以便:
>>> a
array([[ 0., 0., 0.],
[ 0., 0., 1.]])
我们希望所有0值都是NaN。只需使用列表理解。
>>> b = numpy.array([[i if i else numpy.nan for i in j] for j in a])
>>> b
array([[ nan, nan, nan],
[ nan, nan, 1.]])
如果您的特定单元格不会为零,请在理解中指定它们。