2010-05-18 29 views
17

Tengo un archivo CSV, quiero leer este archivo y hacer algunos cálculos previos en cada fila para ver, por ejemplo, que la fila es útil para mí o no y en caso afirmativo, guardo a un nuevo archivo CSV. ¿alguien me puede dar un ejemplo? en más detalles así es como se ven mis datos: (cadena, flotante, flotante) los números son coordenadas.Leyendo un archivo de texto en MATLAB línea por línea

ABC,51.9358183333333,4.183255 
ABC,51.9353866666667,4.1841 
ABC,51.9351716666667,4.184565 
ABC,51.9343083333333,4.186425 
ABC,51.9343083333333,4.186425 
ABC,51.9340916666667,4.18688333333333 

básicamente quiero salvar a las filas que tienen distancias de más de 50 o 50 en un nuevo campo de cadena file.The también debe ser copiada. gracias

+1

bien, para este tipo de cosas, voy a usar 'awk' en lugar de Matlab – Adrien

+1

@Adrien - Estoy de acuerdo: awk 'BEGIN {FS =", "} $ 2> = 50 {print $ 0} ' output.csv – Adrian

Respuesta

9

En realidad se podría utilizar xlsread para lograr esto.Después de colocar primero los datos de la muestra anterior en un archivo 'input_file.csv', aquí es un ejemplo de cómo se pueden obtener los valores numéricos, valores de texto y los datos en bruto en el archivo de las tres salidas de xlsread:

>> [numData,textData,rawData] = xlsread('input_file.csv') 

numData =  % An array of the numeric values from the file 

    51.9358 4.1833 
    51.9354 4.1841 
    51.9352 4.1846 
    51.9343 4.1864 
    51.9343 4.1864 
    51.9341 4.1869 


textData = % A cell array of strings for the text values from the file 

    'ABC' 
    'ABC' 
    'ABC' 
    'ABC' 
    'ABC' 
    'ABC' 


rawData =  % All the data from the file (numeric and text) in a cell array 

    'ABC' [51.9358] [4.1833] 
    'ABC' [51.9354] [4.1841] 
    'ABC' [51.9352] [4.1846] 
    'ABC' [51.9343] [4.1864] 
    'ABC' [51.9343] [4.1864] 
    'ABC' [51.9341] [4.1869] 

Usted luego puede realizar cualquier procesamiento que necesite en los datos numéricos, luego vuelva a guardar un subconjunto de las filas de datos en un nuevo archivo usando xlswrite. He aquí un ejemplo:

index = sqrt(sum(numData.^2,2)) >= 50; % Find the rows where the point is 
             % at a distance of 50 or greater 
             % from the origin 
xlswrite('output_file.csv',rawData(index,:)); % Write those rows to a new file 
+0

¿Esto funcionará si las líneas tienen longitudes diferentes? – Arun

+0

@Arun: Sí, simplemente rellenará 'NaN' para los valores numéricos faltantes y' '' 'para el texto faltante. – gnovice

+0

Gracias por su respuesta. Cuando intento esto, me sale un error de que el archivo .xls no está en el formato correcto. Sin embargo, utilicé dlmread con el archivo de texto original y todo funcionó. – Arun

3

aquí es el documento para leer un csv: http://www.mathworks.com/access/helpdesk/help/techdoc/ref/csvread.html y escribir: http://www.mathworks.com/access/helpdesk/help/techdoc/ref/csvwrite.html

EDITAR

Un ejemplo que funciona:

file.csv:

 
1,50,4.1 
2,49,4.2 
3,30,4.1 
4,71,4.9 
5,51,4.5 
6,61,4.1 

el código:

 
File = csvread('file.csv') 
[m,n] = size(File) 
index=1 
temp=0 
for i = 1:m 
    if (File(i,2)>=50) 
     temp = temp + 1 
    end 
end 
Matrix = zeros(temp, 3) 

for j = 1:m 
    if (File(j,2)>=50) 
     Matrix(index,1) = File(j,1) 
     Matrix(index,2) = File(j,2) 
     Matrix(index,3) = File(j,3) 
     index = index + 1 
    end 
end 
csvwrite('outputFile.csv',Matrix) 

y el resultado del archivo de salida:

 
1,50,4.1 
4,71,4.9 
5,51,4.5 
6,61,4.1 

Esto probablemente no es la mejor solución, pero funciona! Podemos leer el archivo CSV, controlar la distancia de cada fila y guardarla en un archivo nuevo.

Espero que ayude!

+2

De la documentación:" 'csvread' se eliminará en una versión futura. Use' dlmread' en su lugar. " –

+1

Desafortunadamente csvread no lee caracteres. Si solo son números, está bien. Sin embargo, con solo números no necesita todos los bucles, todo lo que necesita es File = csvread ('file.csv'); csvwrite ('outputFile.csv', Archivo (Archivo (:, 2)> = 50, :)); Direccionamiento lógico extraerá todas las filas donde la columna 2 es> = 50. – Adrian

+0

También parece que no maneja comillas, líneas nuevas, etc. como lo haría con una función CSV. Consulte el CSC RFC: http://www.ietf.org/rfc/rfc4180.txt –

7

Si realmente desea procesar el archivo línea por línea, una solución podría ser utilizar fgetl:

  1. Abrir el archivo de datos con fopen
  2. leer la siguiente línea en un array de caracteres usando fgetl
  3. Retreive los datos que necesita el uso de sscanf en el array de caracteres que acaba de leer
  4. Realizar cualquier prueba relevante
  5. Haga lo que desee a otro archivo
  6. Regrese al punto 2 si no ha llegado al final de su archivo.

A diferencia de la respuesta anterior, esto no es muy del estilo de Matlab pero podría ser más eficiente en archivos muy grandes.

Espero que esto ayude.

7

No puede leer cadenas de texto con csvread. Aquí hay otra solución:

fid1 = fopen('test.csv','r'); %# open csv file for reading 
fid2 = fopen('new.csv','w'); %# open new csv file 
while ~feof(fid1) 
    line = fgets(fid1); %# read line by line 
    A = sscanf(line,'%*[^,],%f,%f'); %# sscanf can read only numeric data :(
    if A(2)<4.185 %# test the values 
     fprintf(fid2,'%s',line); %# write the line to the new file 
    end 
end 
fclose(fid1); 
fclose(fid2); 
5

acaba de leer en a MATLAB en un bloque

fid = fopen('file.csv'); 
data=textscan(fid,'%s %f %f','delimiter',','); 
fclose(fid); 

Luego, puede procesarla mediante el direccionamiento lógico

ind50 = data{2}>=50 ; 

ind50 es entonces un índice de las filas donde la columna 2 es mayor que 50. Por lo tanto,

data{1}(ind50) 

listará todas las cadenas para las filas de interés. Entonces sólo tiene que utilizar fprintf para escribir sus datos al nuevo archivo

Cuestiones relacionadas