Eliminar filas no numéricas especificadas

16

En caso de que haya alguna duda: Nan = Non-numeric datatypea los efectos de este desafío.


Escriba un programa o función que tome una matriz / matriz como entrada, así como una lista de índices de columna.

El desafío es eliminar las filas donde están todos los elementos en las columnas especificadas Nan. No importa si otros elementos en la fila son numéricos o no. Con suerte, los siguientes ejemplos aclararán esto (está indexado):

Input array:
    16   NaN     3    13
     5    11   NaN     8
   NaN     7   NaN    12
     4    14   -15     1

Input column index: [1 3]

Output array:
16   NaN     3    13
 5    11   NaN     8
 4    14   -15     1

----

Input array:
    16   NaN     3    13
     5    11   NaN     8
   NaN     7   NaN    12
     4    14   -15     1

Input column index: 3

Output array =
    16   NaN     3    13
     4    14   -15     1

----

Input array:
   NaN   NaN   NaN   NaN
   NaN   NaN   NaN   NaN
   NaN   NaN   NaN   NaN
   NaN   NaN   NaN   NaN

Input column index: 1 2 4

Output array:
 []

Reglas y aclaraciones:

  • La matriz siempre estará vacía.
  • Los valores numéricos serán finitos, pero no necesariamente enteros o valores positivos.
  • El vector índice de la columna puede estar vacío (en cuyo caso no se eliminarán filas)
  • El índice de la columna nunca tendrá valores que excedan las dimensiones de la matriz.
  • Puede suponer que no habrá duplicados en la lista de índice de la columna
  • Puede elegir si desea utilizar valores indexados cero o uno (especifique)
  • Puede tomar la entrada en cualquier formato conveniente
    • La matriz como lista de listas está bien. Los índices de columna pueden ser argumentos separados
  • ans = y similar es aceptado en la salida
  • Usted es libre de elegir qué tipo de datos no numéricos desea usar
    • Debería ser imposible realizar operaciones aritméticas con este tipo de datos, o convertirlo a un número finito utilizando funciones como float(x).

Este es el código de golf, por lo que el código más corto en bytes gana.

Stewie Griffin
fuente

Respuestas:

6

Pyth, 16 19 10 9 7 10 Bytes

Los índices de columna comienzan en cero. La entrada es una lista de listas. Utiliza una cadena vacía como valor no numérico. Toma la lista de índices de columna en la primera línea y la matriz con los valores en la segunda línea.

?Qf-QxkTEE

Pruébalo en línea!

Explicación

?Qf-QxkTEE       # Implicit: Q=column indices, E=Matrix

?Q       E       # If column list is empty no rows get removed
  f     E        # filter the given matrix by each row T
     xkT         # Get the indices of all occurences of an emtpy string (k) 
   -Q            # If the indices match with the given column indices, remove the row

Actualización: Mi primera solución manejó mal una lista vacía de índices de columna. Lo arregló (bastante feo) a un costo de 3 Bytes. Voy a intentar hacerlo mejor después del trabajo ...

Actualización 2: se redujo a 10 9 7 bytes, con algo de ayuda de @FryAmTheEggman y mejorando significativamente el algoritmo.

Actualización 3: Se corrigió un error que @ThomasKwa descubrió. Su solución propuesta de 7 bytes no manejaba correctamente los índices de columnas vacías, por lo que acabo de captar ese caso con un ternario aquí. No veo cómo puedo acortar este cajero automático.

Denker
fuente
1
Puede reemplazar Jcon vzy Kcon Q. zse inicializa a entrada, Qa entrada evaluada.
PurkkaKoodari
@ Pietu1998 ¡Muchas gracias! :) Sabía que me faltaba algo al respecto. Lamentablemente, encontré un error cuando lo miré nuevamente para implementar su sugerencia, lo que en general aumenta mi recuento de bytes hasta que encuentre una solución más agradable.
Denker
1
?KEfnmklKm@TdKQQlas listas vacías son falsas en Pyth, y las declaraciones de asignación devuelven el valor asignado, lo que ahorra algunos bytes. ¡Espero que disfrutes jugando al golf en Pyth! :)
FryAmTheEggman
@FryAmTheEggman Gracias por las sugerencias. Ya no es relevante ya que mejoré mucho el algoritmo, ¡pero realmente aprecio la ayuda! :)
Denker
Muy bonito :) puedes guardar otro byte usando L->fnks@LTQE
FryAmTheEggman
6

JavaScript (ES6), 48 46 bytes

(a,l)=>a.filter(r=>l.some(c=>r[a=0,c]<1/0)||a)

Explicación

Espera una matriz de filas como matrices y una matriz de números indexados en 0 para que las columnas comprueben. Devuelve una matriz de matrices.

Directo filtery some. Comprueba NaNutilizandon < Infinity ( truepara números finitos, falsepara NaNs).

var solution =

(a,l)=>
  a.filter(r=>     // for each row r
    l.some(c=>     // for each column to check c
      r[a=0,       // set a to false so we know the some was executed
        c]<1/0     // if any are not NaN, do not remove the row
    )
    ||a            // default to a because if l is of length 0, some returns false but
  )                //     we must return true
<textarea id="matrix" rows="5" cols="40">16 NaN 3 13
5 11 NaN 8
NaN 7 NaN 12
4 14 -15 1</textarea><br />
<input type="text" id="columns" value="0 2" />
<button onclick="result.textContent=solution(matrix.value.split('\n').map(l=>l.split(' ').map(n=>+n)),(columns.value.match(/\d+/g)||[]).map(n=>+n)).join('\n')">Go</button>
<pre id="result"></pre>

usuario81655
fuente
Buen manejo de ese caso de borde!
Neil
3

CJam, 18 bytes

{{1$\f=_!\se|},\;}

Un bloque (función) sin nombre que espera la matriz y los índices de columna basados ​​en cero en la pila (la matriz en la parte superior), que deja la matriz filtrada en la pila. Estoy usando la matriz vacía ""como valor no numérico.

Pruébalo aquí.

Explicación

{     e# Filter the matrix rows based on the result of this block...
  1$  e#   Copy the column indices.
  \f= e#   Map them to the corresponding cell in the current row.
  _!  e#   Duplicate, logical NOT. Gives 1 for empty column list, 0 otherwise.
  \s  e#   Convert other copy to string. If the array contained only empty arrays, this 
      e#   will be an empty string which is falsy. Otherwise it will contain the numbers 
      e#   that were left after filtering, so it's non-empty and truthy.
  e|  e#   Logical OR.
},
\;    e# Discard the column indices.
Martin Ender
fuente
¿Estoy probando mal o esto viola la regla de que no hay índices de columna dados? The column index vector can be empty (in which case no rows will be removed)
Denker
@DenkerAffe Damn, corregido al costo de 5 bytes ...
Martin Ender
Yo también estuve allí ... Todavía tienes un byte por delante, así que mi plan aún no funcionó: P
Denker
"la matriz vacía """ ¿Quiso decir "la cadena vacía"?
ETHproductions
@ETHproductions No hay diferencia en CJam. Las cadenas son sólo arreglos de caracteres, por lo que []y ""son idénticos y la representación canónica es ""(por ejemplo, que es lo que se obtiene cuando se stringify una matriz vacía).
Martin Ender
3

APL, 19 bytes

{⍵⌿⍨∨/⍬∘≡¨0↑¨⍵[;⍺]}

El argumento izquierdo debe ser una lista de índices (y debe ser una lista, no un escalar), el argumento derecho es la matriz. APL tiene dos tipos de datos, números y caracteres, por lo que esto filtra los tipos de caracteres.

Pruebas:

      m1 m2
   16  NaN    3  13   NaN  NaN  NaN  NaN  
    5   11  NaN   8   NaN  NaN  NaN  NaN  
  NaN    7  NaN  12   NaN  NaN  NaN  NaN  
    4   14  ¯15   1   NaN  NaN  NaN  NaN  
      1 3 {⍵⌿⍨∨/⍬∘≡¨0↑¨⍵[;⍺]} m1
16  NaN    3  13
 5   11  NaN   8
 4   14  ¯15   1
      (,3) {⍵⌿⍨∨/⍬∘≡¨0↑¨⍵[;⍺]} m1
16  NaN    3 13
 4   14  ¯15  1
      1 2 4 {⍵⌿⍨∨/⍬∘≡¨0↑¨⍵[;⍺]} m2 ⍝ this shows nothing
      ⍴1 2 4 {⍵⌿⍨∨/⍬∘≡¨0↑¨⍵[;⍺]} m2 ⍝ the nothing is in fact a 0-by-4 matrix
0 4

Explicación:

  • ⍵[;⍺]: seleccione las columnas dadas de la matriz
  • 0↑¨: tome los primeros 0elementos desde el inicio de cada elemento
  • ⍬∘≡¨: comparar con la lista numérica vacía
  • ∨/: ver en cuál de las filas coincide al menos un elemento
  • ⍵⌿⍨: seleccione esas filas de la matriz
marinus
fuente
2

MATLAB, 32 28 bytes

Contestaré mi propia pregunta por una vez. Lo mejor que puedo hacer en MATLAB es 28 bytes. Tenía la esperanza de evitar el uso de ambos ally de isnanalguna manera, pero aún no he encontrado la manera.

@(A,c)A(any(A(:,c)<inf,2),:)

Prueba:

A =
    35     1   NaN   NaN   NaN    24
     3    32   NaN    21    23    25
    31   NaN   NaN   NaN    27    20
   NaN    28   NaN    17   NaN    15
    30     5   NaN    12    14   NaN
     4    36   NaN    13    18    11

f(A,[3,5])
ans =
     3    32   NaN    21    23    25
    31   NaN   NaN   NaN    27    20
    30     5   NaN    12    14   NaN
     4    36   NaN    13    18    11

Esta es una función anónima sin nombre que toma la matriz de entrada como la primera variable de entrada y una lista de índices de columna como la segunda.

En MATLAB, se NaN < Infevalúa como falso. Se puede suponer que todos los valores son finitos, por lo tanto, verificar si los valores son menores que infes equivalente a verificar si no son numéricos.any(...,2)comprueba si hay valores verdaderos a lo largo de la segunda dimensión (filas). Si ese es el caso, se devolverán esas filas.

Versión antigua:

@(A,c)A(~all(isnan(A(:,c)),2),:)

isnan(A(:,c))devuelve una matriz con booleanos para las columnas especificadas. ~all(isnan(A(:,c)),2)comprueba si todos los valores a lo largo de la segunda dimensión (filas) no son numéricos y lo niega. Esto da como resultado un vector booleano con unos en las posiciones que queremos mantener. A(~all(isnan(A(:,c)),2),:)utiliza la indexación lógica para extraer las filas completas para A.


La siguiente solución de 24 bytes funcionaría si se garantizara que los valores no son cero:

@(A,c)A(any(A(:,c),2),:)
Stewie Griffin
fuente
2

Ruby, 48 bytes

->a,c{a.select{|r|c.map{|i|Fixnum===r[i]}.any?}}

La entrada es índices basados ​​en 0 1 .

Bastante autoexplicativo, en realidad. selectelementos de la matriz donde any?los índices mapped sobre la fila son Fixnums.

Ejecución de muestra:

irb(main):010:0> (->a,c{a.select{|r|c.map{|i|Fixnum===r[i]}.any?}})[[[16,'',3,13],[5,11,'',8],['',7,'',12],[4,14,-15,1]],[0,2]]
=> [[16, "", 3, 13], [5, 11, "", 8], [4, 14, -15, 1]]

1: ¡ Finalmente deletreé esta palabra correctamente en el primer intento! \ o /

Pomo de la puerta
fuente
2

K5, 15 bytes

Esto utiliza columnas indexadas a 0 y la representación matricial de listas de listas naturales de K:

{x@&~&/'^x[;y]}

Indice en la matriz ( x@) las filas donde ( &) no todo de cada ( ~&/') es nulo (^ ).

En acción:

  m: (16 0N 3 13;5 11 0N 8;0N 7 0N 12;4 14 -15 1);
  f: {x@&~&/'^x[;y]};

  f[m;0 2]
(16 0N 3 13
 5 11 0N 8
 4 14 -15 1)

  f[m;2]
(16 0N 3 13
 4 14 -15 1)
JohnE
fuente
2

MATL , 15 16 bytes

tiZ)tn?ZN!XA~Y)

NaNse representa en la entrada como N. La indexación se basa en 1. Por ejemplo, en el primer caso de prueba, la entrada es

[16 N 3 13; 5 11 N 8; N 7 N 12; 4 14 -15 1]
[1 3]

Pruébalo en línea!

Explicación

t       % implicitly input matrix, M. Duplicate
i       % input vector specifying columns
Z)      % matrix N containing those columns of M
tn?     % duplicate matrix N. If non-empty ...
  ZN    %   true for NaN values in matrix N
  !     %   transpose
  XA    %   "all" within each column: gives true for rows of N that contained all NaN's
  ~     %   logical negate
  Y)    %   apply this logical index as a row index into the copy of M that was left
        %   at the bottom of the stack
        % ... implicitly end if
        % implictly display stack contents. If the input vector was empty, the stack
        % contains the original matrix M and an empty matrix. The latter produces no
        % displayed output. If the input vector was non-empty, the stack contains the
        % resulting matrix N
Luis Mendo
fuente
2

R, 49 bytes

function(m,j)m[!!rowSums(!is.nan(m[,j,drop=F])),]

La entrada está basada en 1. La función toma una matriz ( m) y un vector de índices de columna ( j) que pueden faltar.

Dos casos de prueba:

> f <- function(m,j)m[!!rowSums(!is.nan(m[,j,drop=F])),]
> f(m)   
      V1  V2  V3 V4
[1,]  16 NaN   3 13
[2,]   5  11 NaN  8
[3,] NaN   7 NaN 12
[4,]   4  14 -15  1

> f(m, c(1,3))
     V1  V2  V3 V4
[1,] 16 NaN   3 13
[2,]  5  11 NaN  8
[3,]  4  14 -15  1
docendo discimus
fuente
0

Lua, 148 bytes

Una función que toma una matriz y una matriz como entrada, y genera una matriz con las filas correspondientes en nil. Como las matrices son muy parecidas a las matrices de C, nihilar es como free()si el recolector de basura no estuviera muy lejos.

Las matrices están indexadas en 1 en Lua, y uso la cadena "NaN"como un elemento no nominativo.

function f(m,l)c=1 while(c<#m)do x=0 for j=1,#l do x=x+((type(m[c][l[j]])=="number")and 0 or 1)end m[c]=(x<#l and m[c] or nil)c=c+1 end return m end

Puede probar Lua en línea y copiar / pegar la siguiente muestra de código para probar este envío:

-- The function that does the stuff
function f(m,l)
  c=1 
  while(c<#m)
  do 
    x=0 
    for j=1,#l 
    do 
      x=x+((type(m[c][l[j]])=="number")and 0 or 1)
    end
    m[c]=(x<#l and m[c] or nil)
    c=c+1 
   end 
   return m 
end
-- A function to format matrixes into "readable" strings
function printMatrix(matrix,len)
  s="{"
  for v=1,len
  do
    if matrix[v]~=nil
    then
      s=s.."{"..table.concat(matrix[v],",").."}"..(v<len and",\n "or"")
    end
  end
  s=s.."}"
  print(s)
end

nan="NaN"
-- Datas in, indexed as matrices[testCase][row][column]
matrices={{{7,nan,5,3},{5,4,nan,4},{nan,4,nan,9},{5,7,9,8}},
{{16,nan,3,13},{5,11,nan,8},{nan,7,nan,12},{4,14,-15,1}},
{{nan,nan,nan,nan},{nan,nan,nan,nan},{nan,nan,nan,nan},{nan,nan,nan,nan}}}
indexes={{1,3},{3},{1,2,4}}

-- looping so we can test lots of things at once :)
for i=1,#matrices
do
  print("\ninput: "..table.concat(indexes[i]," "))
  printMatrix(matrices[i],4)
  print("output:")
  printMatrix(f(matrices[i],indexes[i]),4)
end
Katenkyo
fuente
0

Mathematica, 52 51 49 46 bytes

Delete[#,Extract[#,{;;,#2}]~Position~{NaN..}]&

La entrada es [matriz como lista de listas, vector de columnas]

Un simmons
fuente
¡Bienvenido a Programming Puzzles & Code Golf! :) Corrija su formato y especifique su formato de entrada, incluida la indexación de las columnas como se le solicitó en el desafío.
Denker
0

Haskell, 39 bytes

m#[]=m
m#r=[l|l<-m,any(<1/0)$map(l!!)r]

Esto utiliza índices basados ​​en 0. Ejemplo de uso (estoy usando sqrt(-1)para crearNaN s):

*Main> [[16,sqrt(-1),3,13], [5,11,sqrt(-1),8], [sqrt(-1),7,sqrt(-1),12], [4,14,-15,1]] # [0,2]
[[16.0,NaN,3.0,13.0],[5.0,11.0,NaN,8.0],[4.0,14.0,-15.0,1.0]]

Es solo un filtro simple como se ve en otras respuestas a través de la comprensión de la lista. El caso especial de una lista de índice vacía se detecta por separado.

nimi
fuente