什么是删除数组之间重复的最有效方法,而不是WITHIN?

时间:2016-11-04 18:13:20

标签: python arrays pandas numpy

我不是在寻找数组中的唯一值。我想删除任何其他数组中的元素。例如:

df = pd.DataFrame({'area': a, 'orDate': b, 'orNo': c})
    area      orDate  orNo
0    1.0  20160926.0  10.0
1    2.0  20160926.0  20.0
2    1.0  20160926.0  10.0
3    1.0  20160926.0  10.0
4    2.0  20160926.0  30.0
5    2.0  20160926.0  20.0
6    2.0  20160926.0  40.0
7    2.0  20160927.0  50.0
8    1.0  20160927.0  60.0
9    1.0  20160927.0  20.0
10   3.0  20160927.0  30.0
11   3.0  20160927.0  80.0
12   3.0  20160927.0  90.0
13   3.0  20160927.0  20.0
gb=df.groupby(['area','orDate'])['orNo'].unique().reset_index()
   area      orDate                      orNo
0   1.0  20160926.0                    [10.0]
1   1.0  20160927.0              [60.0, 20.0]
2   2.0  20160926.0        [20.0, 30.0, 40.0]
3   2.0  20160927.0                    [50.0]
4   3.0  20160927.0  [30.0, 80.0, 90.0, 20.0]
I want:
0   1.0  20160926.0                    [10.0]
1   1.0  20160927.0                    [60.0]
2   2.0  20160926.0                    [40.0]
3   2.0  20160927.0                    [50.0]
4   3.0  20160927.0              [80.0, 90.0]
orNo 20,30,40 are seen more than once. So should be deleted.

1 个答案:

答案 0 :(得分:1)

这是一个几乎*矢量化的方法 -

lens = np.array(map(len,arr))
vals = np.concatenate(arr)
unq,c = np.unique(vals,return_counts=1)
dup_vals = unq[c>1]
valid_mask = ~np.in1d(vals,dup_vals)
out_vals = vals[valid_mask]
cut_idx = valid_mask.cumsum()[lens.cumsum()-1]
out = np.split(out_vals,cut_idx)[:-1]

如果您无权访问支持return_counts np.unique的最新版本的NumPy,则可以使用dup_vals获取np.bincount的替代方法,假设输入数组中有non-negative个数字 -

dup_vals = np.nonzero(np.bincount(vals)>1)[0]

此外,获取cut_idx的另一种方法是使用np.searchsorted -

cut_idx = np.searchsorted(np.nonzero(valid_mask)[0],lens.cumsum())

*:几乎是因为在第一步使用了map,但是在那里使用它来获得输入数组中每个列表的长度,它对性能的影响应该很小。

循环方式,这是另一个,一旦你有dup_vals,循环理解 -

out = [np.setdiff1d(i,dup_vals) for i in arr]