【问题标题】:How to remove certain values from an array, that does not meet a criteria?如何从数组中删除不符合条件的某些值?
【发布时间】:2017-01-07 11:33:11
【问题描述】:

如果我有一个由数字组成的数组,比如说

A = [1.3, 2.2, 2.3,4.2, 5.1, 3.2, 5.3, 3.3, 2.1,1.1, 5.2, 3.1]

我想提取只有整数在数组中的数字,然后是 .1、.2 和 .3。例如,我不想在我的新数组中包含 1,因为 A 中不存在 1.2。我想包含 5,因为 5.1、5.2 和 5.3 都在 A 中。我该怎么做呢?接受 MatLab 或 Python 答案!

编辑** 谢谢你。我现在意识到,我可能问错了问题,而不是打印具有小数点 .1、.2、.3 的整数,我希望最终数组包含来自 A 的浮点数,但只有具有两者的浮点数.1,.2,.3 后面是同一个整数。对不起!

【问题讨论】:

  • 这是关于 Python 还是 Matlab?
  • 我会很高兴得到任何一种语言的答案。
  • 在问题中添加预期的输出矩阵会很有帮助
  • 会的!在这个例子中,它应该是 out = [2.2 ,2.3 ,2.1 ,3.1 ,3.2 ,3.3 ,5.1 ,5.2 ,5,3]

标签: python arrays matlab loops vector


【解决方案1】:

MATLAB 中(可能不是最好的算法):

clc; clear;

tolerance = 10^(-15);
% Tolerance is useful in order to compare arrays, because the "==" operator
% can lean to wrong results.

% The fractional parts we are interested in.
desirable_list = [0.1 0.2 0.3];

% Because we are going to work with ordered lists, we order the
% desirable_list as well.
desirable = sort(desirable_list, 'ascend');

% Our list and the sorted list.
A = [1.3, 2.2, 2.3, 4.2, 5.1, 3.2, 5.3, 3.3, 2.1, 1.1, 5.2, 3.1];
A_sorted = sort(A);

% Getting the integer parts (uniquely) of our list.
integer_parts = unique(fix(A));

% Getting the elements that satisfy our criteria in an ordered list in an
% array called S.
S = [];
for j = integer_parts
    m1 = (A_sorted(fix(A_sorted) == j));
    if m1 < 0
        m1 = sort(m1, 'descend');
    end


    if length(m1) == length(desirable) & abs(abs(m1) - desirable) < abs(j) + tolerance
        S = [S m1];
    end
end

% Getting the elements we are interested in, in the specific order they
% appear in our original list.

V = zeros(1,length(S));
l = 1;
for k = 1:length(A)
    if ismember(A(k), S)
        V(l)= A(k);
        l = l + 1;
    end
end
A
V

输出:

A =

    1.3000    2.2000    2.3000    4.2000    5.1000    3.2000    5.3000    3.3000    2.1000    1.1000    5.2000    3.1000


V =

    2.2000    2.3000    5.1000    3.2000    5.3000    3.3000    2.1000    5.2000    3.1000

>> 

【讨论】:

  • 谢谢。我现在意识到,我可能问错了问题,而不是打印具有小数点 .1、.2、.3 的整数,我希望最终数组包含来自 A 的浮点数,但只有具有两者的浮点数.1,.2,.3 后面是同一个整数。对不起!
  • 有什么办法可以让输出 S 以与 A 中相同的顺序返回值?例如,A S = [2.2000 2.3000 5.1000 3.2000 5.3000...]
  • 该死,非常感谢!随时学习新事物
【解决方案2】:

使用 Python 你可以做到:

import numpy as np
A = [1.3, 2.2, 2.3, 4.2, 5.1, 3.2, 5.3, 3.3, 2.1, 1.1, 5.2, 3.1]
b = set([int(i) for i in A if np.all([j in A for j in (np.array([1, 2, 3]) + 10*int(np.floor(i)))/10.0])])

b 在哪里

set([2, 3, 5])

(可以使用list 轻松转换为列表)。

评论

我乘以10 并除以10.0 以尽量避免浮点运算问题。如果您希望比较是基于数字还是基于字符串,问题中并不清楚。

【讨论】:

    【解决方案3】:

    使用 Python,您可以使用 itertools.groupby 将浮点数按其截断值分组,并检查小数是否是 [1,2,3] 的超集:

    from itertools import groupby
    needed_decimals = set([1, 2, 3])
    
    a = [1.3, 2.2, 2.3,4.2, 5.1, 3.2, 5.3, 3.3, 2.1,1.1, 5.2, 3.1]
    
    pairs = [tuple(int(y) for y in str(x).split('.')) for x in sorted(a)]
    #=> [(1, 1), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3), (4, 2), (5, 1), (5, 2), (5, 3)]
    integers = [integer for integer, numbers in groupby(pairs, lambda x: x[0]) if set(x[1] for x in numbers) >= needed_decimals]
    #=> [2,3,5]
    

    【讨论】:

      【解决方案4】:

      Python 中,您可以:

      import operator
      
      A = [1.3, 2.2, 2.3,4.2, 5.1, 3.2, 5.3, 3.3, 2.1,1.1, 5.2, 3.1]
      
      s = set(int(str(i).split('.')[0]) for i in A)
      
      res = []
      for n in s:
          if all(x in A for x in map(operator.add, [n, n, n], [0.1, 0.2, 0.3])):
              res.append(n)
      

      输出:

      >>> res
      [2, 3, 5]
      

      编辑:

      如果您想要获得在同一整数后面具有 .1、.2 和 .3 的浮点数,请尝试以下操作:

      for n in s:
          temp = map(operator.add, [n, n, n], [0.1, 0.2, 0.3])
          if all(x in A for x in temp):
              res.extend(temp)
      

      输出:

      >>> res
      [2.1, 2.2, 2.3, 3.1, 3.2, 3.3, 5.1, 5.2, 5.3]
      

      【讨论】:

      • 条件太弱:匹配[1.1,1.1,1.1]
      • @EricDuminil,你说得对,我刚刚修好了,谢谢!
      【解决方案5】:

      一个MATLAB解决方案:(因问题更新而更新)

      A = [1.3, 2.2, 2.3,4.2, 5.1, 3.2, 5.3, 3.3, 2.1,1.1, 5.2, 3.1]
      INC = [.1 .2 .3];
      F = floor(A);
      U = unique(F,'stable');
      %find unique  values of F
      B = bsxfun(@plus,U,INC.');
      %with broadcasting sum each element with [.1 .2 .3]
      %in MATLAB R2016b you can write B = U + INC.';
      IDX = all(ismember(B,A));
      %for each integer I if  I+[.1 .2 .3] exist in the array return index of it
      OUT =B(:,IDX);
      %extract output
      

      更紧凑的形式:

      B = bsxfun(@plus,unique(floor(A),'stable'),INC.');
      OUT = B(:,all(ismember(B,A)))
      

      在 MATLAB R2016b 或 Octave 中可以写成:

      B = unique(floor(A),'stable') + INC.';
      OUT = B(:, all(ismember(B,A)))
      

      结果

      OUT =
      
         2.1000   3.1000   5.1000
         2.2000   3.2000   5.2000
         2.3000   3.3000   5.3000
      

      【讨论】:

      • 谢谢。我现在意识到,我可能问错了问题,而不是打印具有小数点 .1、.2、.3 的整数,我希望最终数组包含来自 A 的浮点数,但只有具有两者的浮点数.1,.2,.3 后面是同一个整数。对不起!
      【解决方案6】:

      set([x for x in map(int,l) if all([float(str(x)+'.' + str(e)) in l for e in [1,2,3 ]])])

      在一行中完成技巧

      【讨论】:

        猜你喜欢
        • 2019-04-30
        • 2020-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-17
        • 1970-01-01
        • 1970-01-01
        • 2019-02-23
        相关资源
        最近更新 更多