2017-02-16 40 views
1

我有一個大的CSV文件文件夾(文件夾中的大約25,000個文件,它會進一步增加),也就是說,幾乎所有文件都有比Excel的行限制更多的行限制是100萬的東西,我猜)。所有這些CSV文件在每行中都有5個由逗號分隔的元素,並且所有文件中的行數(信息)都不相同。處理大型CSV文件的文件夾

One CSV File: 
a1,b1,c1,d1,e1 
a2,b2,c2,d2,e2 
. 
. 
. 
a3152685,b3152685,c3152685,d3152685,e3152685 

My Reference File: 
x1,y1 
x2,y2 
x3,y3 
. 
. 
. 
x397,y397 

我基本上只需要從每個基於我的參考文件的CSV文件中訪問這些行中的一部分(大約400)。無論我在任何CSV文件中匹配xy夫婦與ab夫婦,我都會將a,b,c,d,e行與CSV文件的標題一起保存到其他地方,最好是Excel文件,但我願意接受。

我可以使用Matlab,Python 2.7,MS Access(將CSV文件轉換爲數據庫文件,如果我不必爲每個單個文件執行操作,這似乎是一個好主意 - 是否有批量版本可以做到這一點? )或MS Excel。我從來沒有做過任何VBA的東西,但如果你有一些VBA解決這個問題,我也樂於聽到這個。

讓我知道如果您不清楚您是否需要更多的說明。

+0

您可以使用帶有Excel的ADO來引用文本文件。 – Fionnuala

+0

無論是MATLAB還是python,這都是微不足道的。打開文件,逐行閱讀直到開心,保存數據。 –

回答

1

只是萬一有人需要答案,我有點用MATLAB來處理它。

MATLAB中的數據存儲功能就是我一直在尋找的功能。

ds = datastore(MyReferenceFile); 
TableExtracted = readall(ds); 

然後剩下的只是find(ismember)負責。

還有datastore的批次查找功能(該批次的大小分配在ReadSize);但是,它默認爲20000,我想這也是限制。這對我的喜好來說太慢了,所以我使用了readall,而且速度還是相當快的。

1

你可以找到辦公products here

Matlab是很好的與此大型文件和大型文件集的工作極限。 2014版對csv這個引人入勝的數據存儲有了很多改進,現在對於excel文件也可以很好地工作。

看看這個教程:

http://blogs.mathworks.com/loren/2014/12/03/reading-big-data-into-matlab/

我有一個3 CSV文件(文件[1-3]的.csv)含有這樣的:

a1,b1,c1,d1,e1 
a2,b2,c2,d2,e2 
a3,b3,c3,d3,e3 
a4,b4,c4,d4,e4 
a5,b5,c5,d5,e5 
a6,b6,c6,d6,e6 
a7,b7,c7,d7,e7 
a8,b8,c8,d8,e8 
a9,b9,c9,d9,e9 
a10,b10,c10,d10,e10 

和文件varnames對於列的名稱:

ABCDE

讓我們來讀取文件:

>> datafile = 'csv-files/file1.csv'; 
>> headerfile = 'csv-files/varnames.txt' 

>> fileID = fopen(headerfile); 
>> varnames = textscan(fileID,'%s'); 
>> varnames = varnames{:}; 

ds = datastore(datafile,'ReadVariableNames',false); 

>> ds.VariableNames = varnames 


ds = 

    TabularTextDatastore with properties: 

         Files: { 
          '/home/anquegi/learn/matlab/stackoverflow/csv-files/file1.csv' 
          } 
       FileEncoding: 'UTF-8' 
      ReadVariableNames: false 
       VariableNames: {'A', 'B', 'C' ... and 2 more} 

    Text Format Properties: 
      NumHeaderLines: 0 
        Delimiter: ',' 
       RowDelimiter: '\r\n' 
      TreatAsMissing: '' 
       MissingValue: NaN 

    Advanced Text Format Properties: 
      TextscanFormats: {'%q', '%q', '%q' ... and 2 more} 
     ExponentCharacters: 'eEdD' 
       CommentStyle: '' 
       Whitespace: ' \b\t' 
    MultipleDelimitersAsOne: false 

    Properties that control the table returned by preview, read, readall: 
     SelectedVariableNames: {'A', 'B', 'C' ... and 2 more} 
      SelectedFormats: {'%q', '%q', '%q' ... and 2 more} 
        ReadSize: 20000 rows 


>> preview(ds) 

ans = 

    A  B  C  D  E 
    ____ ____ ____ ____ ____ 

    'a1' 'b1' 'c1' 'd1' 'e1' 
    'a2' 'b2' 'c2' 'd2' 'e2' 
    'a3' 'b3' 'c3' 'd3' 'e3' 
    'a4' 'b4' 'c4' 'd4' 'e4' 
    'a5' 'b5' 'c5' 'd5' 'e5' 
    'a6' 'b6' 'c6' 'd6' 'e6' 
    'a7' 'b7' 'c7' 'd7' 'e7' 
    'a8' 'b8' 'c8' 'd8' 'e8' 

如果我們看一下我們採取的參數READSIZE是READSIZE:20000行,因此matlab的每次讀取20000行,你可以處理。由於數據只有10行,我將其更改爲三:

>> ds.ReadSize=3 

ds = 

    TabularTextDatastore with properties: 

         Files: { 
          '/home/anquegi/learn/matlab/stackoverflow/csv-files/file1.csv' 
          } 
       FileEncoding: 'UTF-8' 
      ReadVariableNames: false 
       VariableNames: {'A', 'B', 'C' ... and 2 more} 

    Text Format Properties: 
      NumHeaderLines: 0 
        Delimiter: ',' 
       RowDelimiter: '\r\n' 
      TreatAsMissing: '' 
       MissingValue: NaN 

    Advanced Text Format Properties: 
      TextscanFormats: {'%q', '%q', '%q' ... and 2 more} 
     ExponentCharacters: 'eEdD' 
       CommentStyle: '' 
       Whitespace: ' \b\t' 
    MultipleDelimitersAsOne: false 

    Properties that control the table returned by preview, read, readall: 
     SelectedVariableNames: {'A', 'B', 'C' ... and 2 more} 
      SelectedFormats: {'%q', '%q', '%q' ... and 2 more} 
        ReadSize: 3 rows 

>> reset(ds) 
while hasdata(ds) 
     T = read(ds); 
     T.A 
end 

ans = 

    'a1' 
    'a2' 
    'a3' 


ans = 

    'a4' 
    'a5' 
    'a6' 


ans = 

    'a7' 
    'a8' 
    'a9' 


ans = 

    'a10' 

那麼變量t是,你可以把它寫在那裏,你想有一個表:請注意,每次讀(DS)是移動的號碼通過readsie分配線,這個參數可以是行,或者這也許是題外話文件

>> reset(ds) 
>> T = read(ds); 
>> T 

T = 

    A  B  C  D  E 
    ____ ____ ____ ____ ____ 

    'a1' 'b1' 'c1' 'd1' 'e1' 
    'a2' 'b2' 'c2' 'd2' 'e2' 
    'a3' 'b3' 'c3' 'd3' 'e3' 

>> writetable(T,'mySpreadsheet','FileType','spreadsheet') 
>> reset(ds) 
0

,但我認爲你應該考慮SQL Server和SSIS。您可以輕鬆地遍歷文件夾中的所有文件,全部加載到SQL Server中,然後將文件移出文件夾。下一次將文件轉儲到您的文件夾中,再次運行該過程,在這些新文件上。所有細節請參閱下面的鏈接。

https://www.mssqltips.com/sqlservertip/2874/loop-through-flat-files-in-sql-server-integration-services/

或者,使用純SQL做的工作。

--BULK INSERT MULTIPLE FILES From a Folder 

--a table to loop thru filenames drop table ALLFILENAMES 
CREATE TABLE ALLFILENAMES(WHICHPATH VARCHAR(255),WHICHFILE varchar(255)) 

--some variables 
declare @filename varchar(255), 
     @path  varchar(255), 
     @sql  varchar(8000), 
     @cmd  varchar(1000) 


--get the list of files to process: 
SET @path = 'C:\Dump\' 
SET @cmd = 'dir ' + @path + '*.csv /b' 
INSERT INTO ALLFILENAMES(WHICHFILE) 
EXEC Master..xp_cmdShell @cmd 
UPDATE ALLFILENAMES SET WHICHPATH = @path where WHICHPATH is null 


--cursor loop 
declare c1 cursor for SELECT WHICHPATH,WHICHFILE FROM ALLFILENAMES where WHICHFILE like '%.csv%' 
open c1 
fetch next from c1 into @path,@filename 
While @@fetch_status <> -1 
    begin 
    --bulk insert won't take a variable name, so make a sql and execute it instead: 
    set @sql = 'BULK INSERT Temp FROM ''' + @path + @filename + ''' ' 
     + '  WITH ( 
       FIELDTERMINATOR = '','', 
       ROWTERMINATOR = ''\n'', 
       FIRSTROW = 2 
      ) ' 
print @sql 
exec (@sql) 

    fetch next from c1 into @path,@filename 
    end 
close c1 
deallocate c1 


--Extras 

--delete from ALLFILENAMES where WHICHFILE is NULL 
--select * from ALLFILENAMES 
--drop table ALLFILENAMES 

從這裏:

Import Multiple CSV Files to SQL Server from a Folder

訪問不會處理日期的這個數量,並且你已經知道,Excel將甚至不能接近。

一個更需要考慮的就是用R,這是完全免費的,速度非常快。

我們經常會遇到,我們在多個文件中的數據,以不同的頻率和意見的不同子集的情況,但我們想將它們相互匹配的全面而系統地。在R中,merge()命令是將兩個數據幀匹配在一起的好方法。

剛讀出的兩個數據幀分成R

mydata1 = read.csv(path1, header=T) 
mydata2 = read.csv(path2, header=T) 

然後,合併

myfulldata = merge(mydata1, mydata2) 

只要mydata1和mydata2有具有相同名稱的至少一個共同的列(其允許匹配觀測在mydata1中觀察mydata2),這將像魅力一樣工作。它也需要三條線。

如果我有20個文件與我想匹配觀測到觀測數據?假設他們都有一個允許合併的公共列,我仍然需要閱讀(20行代碼)中的20個文件和merge()兩個二行的文件......所以我可以將20個數據幀與19個合併語句合併在一起像這樣:

mytempdata = merge(mydata1, mydata2) 
mytempdata = merge(mytempdata, mydata3) 
. 
. 
. 
mytempdata = merge(mytempdata, mydata20) 

這很乏味。您可能正在尋找更簡單的方法。如果你是,我寫了一個函數來解決你的困境稱爲multmerge()*下面的代碼來定義函數:

multmerge = function(mypath){ 
filenames=list.files(path=mypath, full.names=TRUE) 
datalist = lapply(filenames, function(x){read.csv(file=x,header=T)}) 
Reduce(function(x,y) {merge(x,y)}, datalist) 

運行代碼來定義功能後,你都設置爲使用它。該功能需要一個路徑。這個路徑應該是一個文件夾的名稱,該文件夾包含您想要讀取和合並在一起的所有文件,以及僅包含您想要合併的文件。考慮到這一點,我有兩個提示:

在使用此函數之前,我的建議是在一個短目錄中創建一個新文件夾(例如,該文件夾的路徑可以是「C:// R// mergeme「)並保存您想要合併到該文件夾​​中的所有文件。 另外,請確保將執行匹配的列在每個文件中的格式都是相同的(並且具有相同的名稱)。 假設您將20個文件保存到「C:// R // mergeme」的mergeme文件夾中,並且您想要讀取併合並它們。用我的功能,您使用的語法如下:

mymergeddata = multmerge(「C://R//mergeme」) 

運行此命令後,你有你所有的變量相互匹配的完全合併的數據幀。當然,匹配和合並數據的大部分細節都歸結爲確保公共列被正確指定,但是鑑於此,該函數可以爲您節省大量的輸入。

一旦一切都合併到1個的數據幀,出口是到一個文本文件或CSV文件,並批量載荷到SQL Server。