如何合并具有Nan值的数组列?

时间:2019-02-12 06:22:32

标签: python python-3.x numpy

我是python的初学者,在合并数据时遇到一些问题。

我要做的是处理数据,完全丢弃具有Nan值的列。

但是我的大部分数据中Nan值的索引都不同。

例如,

data1 = np.array([1, 2, np.nan, 4, 5])
data2 = np.array([1, np.nan, 3, 4, 6])
data3 = np.array([np.nan, 2, 3, 4, 7])

ind_1 = np.where(~np.isnan(data1))
ind_2 = np.where(~np.isnan(data2))
ind_3 = np.where(~np.isnan(data3))

-----

data1_out = data1[ind_1[0]]  # array([ 1., 2., 4., 5.])
data2_out = data2[ind_2[0]]  # array([ 1., 3., 4., 6.])
data3_out = data3[ind_3[0]]  # array([ 2., 3., 4., 7.])

但是我需要的是一个像这样的数组

data1_out = array([ 4., 5.])
data2_out = array([ 4., 6.])
data3_out = array([ 4., 7.])

所以我认为组合数组就像

ind_c = intersection(ind_1, ind_2, ind_3)
data1_out = data1[ind_c[0]]

将解决问题!

与其他共享输出,因此,如果一个数据集的索引具有Nan值,则会影响另一数据集的所有相同索引。

我找不到执行此操作的简单方法。有什么建议吗?

3 个答案:

答案 0 :(得分:2)

>>> truth = ~np.isnan(data1) & ~np.isnan(data2) & ~np.isnan(data3)
>>> data1[truth]
[4. 5.]
>>> data2[truth]
[4. 5.]
>>> data3[truth]
[4. 5.]

答案 1 :(得分:1)

有一个非常简单的方法可以做到这一点。与其使用where获取数字索引,不如使用isnan生成的布尔掩码。遮罩更易于组合,并且通常也更易于以其他方式使用,更不用说它为每个阵列节省了一步。

mask_1 = ~np.isnan(data1)
mask_2 = ~np.isnan(data2)
mask_3 = ~np.isnan(data3)

现在,您可以使用简单的布尔运算将掩码合并为一个,并将结果应用于每个数组:

mask = mask_1 & mask_2 & mask_3
data1_out = data1[mask] 
data2_out = data2[mask] 
data3_out = data3[mask] 

现在,每当您发现自己使用名称为x1x2x3等的形状相同的数组时,您可能只需要一个具有额外维度的数组。 99%的时间将使您的生活更轻松:

data = np.array([[1, 2, np.nan, 4, 5],
                 [1, np.nan, 3, 4, 6],
                 [np.nan, 2, 3, 4, 7]])
mask = ~np.isnan(data).any(axis=0)
data_out = data[np.arange(data.shape[0]).reshape(-1, 1), mask]

any|应用于所有元素。 np.arange(data.shape[0]).reshape(-1, 1)创建一个列向量,该列向量通过广播将一维掩码强制应用于每一行。

当然,此方法基于每行中有相等数量的NaN。如果不是这种情况,则实际上必须使用单独的数组。

答案 2 :(得分:0)

将所有数组合并为2D数组:

z = np.stack([data1, data2, data3])

找到非Nan列:

columns = ~np.isnan(z).any(axis=0)

选择数据:

data1, data2, data3 = z[:, columns]
#array([4., 5.])
#....