PDA

View Full Version : تبدیل داده های عددی به سلولی در حجم زیاد



hamidkor
یک شنبه 10 فروردین 1393, 14:53 عصر
باسلام دوستان عزیز میخواستم نظر کارشناسانه ی شما رو در مورد تبدیل داده های عددی به سلولی (num2cell) در ابعاد بالا مثل یک میلیون در دویست بدونم؟ من تو این موضوع موقع اجرا با خطای کمبود حافظه موجه می شوم! ممنون خواهم شد اگر بغیر از افزایش حافظه و چند قسمت کردن ماتریس اصلی پیشنهاد دیگه ای داشته باشین؟

rahnema1
یک شنبه 10 فروردین 1393, 22:24 عصر
سلام
اگه فرض کنیم داده های شما از نوع double باشه هر عدد 8 بایت جا می گیره که برای 200 میلیون برای ماتریس و سلول مورد نظر میشه تقریبا 3 گیگ حافظه. اگه دقت بالا مهم نیست و دامنه اعداد هم بالا نباشه می تونید به جای double از single استفاده کنید که نصف اون جا می گیره. یا اگه اعداد از نوع صحیح باشن بسته به دامنه اعداد شما می تونید از یکی از انواع int8,uint8,int16,uint16,int32,uint32 که به ترتیب 2/1 و 4/1 و 8/1 نسبت به double جا اشغال می کنند

niloofar_f
یک شنبه 10 فروردین 1393, 22:37 عصر
باسلام دوستان عزیز میخواستم نظر کارشناسانه ی شما رو در مورد تبدیل داده های عددی به سلولی (num2cell) در ابعاد بالا مثل یک میلیون در دویست بدونم؟ من تو این موضوع موقع اجرا با خطای کمبود حافظه موجه می شوم! ممنون خواهم شد اگر بغیر از افزایش حافظه و چند قسمت کردن ماتریس اصلی پیشنهاد دیگه ای داشته باشین؟

سلام
روشی که به ذهن من میرسه استفاده از دستورات موازی و توزیع شده در متلب هست. مثلا میتونید با استفاده از دستور spmd ماتریس با بعد بزرگ رو بین پردازنده ها توزیع کنید.
ضمنا برای رفع مشکل حافظه از متلب 64بیتی روی سیستم عامل 64بیتی استفاده کنید.

برای مطالعه این دستور pdf موجود در لینک زیر رو میتونید مطلالعه کنید:
http://barnamenevis.org/showthread.php?440637-%D9%BE%D8%B1%D8%AF%D8%A7%D8%B2%D8%B4-%D9%85%D9%88%D8%A7%D8%B2%DB%8C

امیدوارم مفید باشه!

hamidkor
سه شنبه 12 فروردین 1393, 22:28 عصر
سلام اگه فرض کنیم داده های شما از نوع double باشه هر عدد 8 بایت جا می گیره که برای 200 میلیون برای ماتریس و سلول مورد نظر میشه تقریبا 3 گیگ حافظه. اگه دقت بالا مهم نیست و دامنه اعداد هم بالا نباشه می تونید به جای double از single استفاده کنید که نصف اون جا می گیره. یا اگه اعداد از نوع صحیح باشن بسته به دامنه اعداد شما می تونید از یکی از انواع int8,uint8,int16,uint16,int32,uint32 که به ترتیب 2/1 و 4/1 و 8/1 نسبت به double جا اشغال می کنند

ضمن تشکر از توضیحات ارزندتون لازم میدونم این نکته رو عرض کنم که داده های مورد نظر قبل از تبدیل به حالت سلولی به صورت single هستند و با این وجود هنگام تبدیل این حجم داده به داده های سلولی با مشکل مواجه میشم! درضمن داده ها صحیح هم نیستن و برخی اعشاری هستند.

hamidkor
سه شنبه 12 فروردین 1393, 22:41 عصر
سلام
روشی که به ذهن من میرسه استفاده از دستورات موازی و توزیع شده در متلب هست. مثلا میتونید با استفاده از دستور spmd ماتریس با بعد بزرگ رو بین پردازنده ها توزیع کنید.
ضمنا برای رفع مشکل حافظه از متلب 64بیتی روی سیستم عامل 64بیتی استفاده کنید.

برای مطالعه این دستور pdf موجود در لینک زیر رو میتونید مطلالعه کنید:
http://barnamenevis.org/showthread.php?440637-%D9%BE%D8%B1%D8%AF%D8%A7%D8%B2%D8%B4-%D9%85%D9%88%D8%A7%D8%B2%DB%8C

امیدوارم مفید باشه!

ضمن تشکر از پیشنهادتون باید خدمتتون عرض کنم که تو صفحه ای که لینکشو گذاشتین لینکی واسه فایل پی دی اف موضوع پیشنهادیتون هستش که خرابه گویا و دسترسی بهش نیست! ولی از هلپ متلب موضوع رو پیگری خواهم کرد. امیدوارم که کارساز باشه، بازم از راهنماییتون سپاسمندم

niloofar_f
سه شنبه 12 فروردین 1393, 23:39 عصر
ضمن تشکر از پیشنهادتون باید خدمتتون عرض کنم که تو صفحه ای که لینکشو گذاشتین لینکی واسه فایل پی دی اف موضوع پیشنهادیتون هستش که خرابه گویا و دسترسی بهش نیست! ولی از هلپ متلب موضوع رو پیگری خواهم کرد. امیدوارم که کارساز باشه، بازم از راهنماییتون سپاسمندم

منظورم پست 15 و درادامه اون 16 از این لینک بود: http://barnamenevis.org/showthread.php?440637-%D9%BE%D8%B1%D8%AF%D8%A7%D8%B2%D8%B4-%D9%85%D9%88%D8%A7%D8%B2%DB%8C&p=1972108&viewfull=1#post1972108

امیدوارم جواب بده! موفق باشید.

rahnema1
چهارشنبه 13 فروردین 1393, 00:25 صبح
یک کار دیگه هم میشه کرد
ابتدا ماتریس را با استفاده از fwrite داخل یک فایل بریزید
بعد هم یک آرایه سلولی خالی با ابعاد مورد نظر درست کنید و بعد از اون با استفاده از fread خورده خورده مقادیر را از فایل بخونید و داخل آرایه سلولی بریزید (مثلا 200 بار این دستور را اجرا کنید و در هر دفعه یک میلیون بخونید)

hamidkor
چهارشنبه 13 فروردین 1393, 02:24 صبح
یک کار دیگه هم میشه کرد
ابتدا ماتریس را با استفاده از fwrite داخل یک فایل بریزید
بعد هم یک آرایه سلولی خالی با ابعاد مورد نظر درست کنید و بعد از اون با استفاده از fread خورده خورده مقادیر را از فایل بخونید و داخل آرایه سلولی بریزید (مثلا 200 بار این دستور را اجرا کنید و در هر دفعه یک میلیون بخونید)


مثل اینکه منظوررو بد رسوندم! ابعاد ماتریس یه میلیون در 200 هستش! (200*1000000) ، بعدشم هدفم از تبدیل داده های عددی به سلولی ترکیب آنها با داده های رشته ای و رایت آنها باهم تو یه فایل متنی (txt) است بنابراین لازمه که هر دو نوع داده ی عددی و رشته ای رو به سلولی تبدیل و اونها رو باهم ترکیب کنم تا به فایل مورد نظرم برسم. فرض کنید A داده های رشته ای و B داده ای عدد هستند و ما اگر بخواهیم اینها رو به گونه ای تو یه فایل متنی رایت کنیم که داده های رشته ای بصورت عنوان داده های عددی باشند (ماتریس C) بنابراین باید آنها را به داده های سلولی تبدیل و سپس باهم ترکیب نماییم
A={a b c};
B=[1 2 3];
C={a d c;1 2 3};

rahnema1
چهارشنبه 13 فروردین 1393, 06:47 صبح
اتفاقا من هم واسه همین گفتم توی فایل بنویسید واسه اینکه حجم داده ها در حافظه زیاده. ما ابتدا ماتریس را به یک فایل منتقل می کنیم بعد اون ماتریس را از حافظه پاک می کنیم ( یا اصلا کلا متلب را می بندیم و دو باره اجرا می کنیم. الان دیگه ماتریس روی حافظه نیست) سپس از روی اون فایل خورده خورده می خونیم و داخل سلول می ریزیم
در هر صورت اینکه شما می خواهید توی یک فایل متنی بریزید فکر کنم نیازی به اینها نباشه. برنامه زیر را ببینید مثلا عنوان یک آرایه سلولی 1 در 3 و مقادیر هم یک ماتریس 100 در 3 هست این صور در یک فایل متنی بنویسید که با کاما از هم جدا شده باشند

A={'a','b','c'};
B=randn(100,3);
fid=fopen('myFile.csv','wt');
[rows,cols]=size(A)

for i=1:rows

fprintf(fid,'%s,',A{i,1:end-1})
fprintf(fid,'%s\n',A{i,end})
end

dlmwrite(fid,B,'-append');
fclose(fid);

بخش بیشتر کد را از این سایت گرفتم:
http://www.mathworks.com/matlabcentral/answers/97487

hamidkor
چهارشنبه 13 فروردین 1393, 10:36 صبح
اتفاقا من هم واسه همین گفتم توی فایل بنویسید واسه اینکه حجم داده ها در حافظه زیاده. ما ابتدا ماتریس را به یک فایل منتقل می کنیم بعد اون ماتریس را از حافظه پاک می کنیم ( یا اصلا کلا متلب را می بندیم و دو باره اجرا می کنیم. الان دیگه ماتریس روی حافظه نیست) سپس از روی اون فایل خورده خورده می خونیم و داخل سلول می ریزیم در هر صورت اینکه شما می خواهید توی یک فایل متنی بریزید فکر کنم نیازی به اینها نباشه. برنامه زیر را ببینید مثلا عنوان یک آرایه سلولی 1 در 3 و مقادیر هم یک ماتریس 100 در 3 هست این صور در یک فایل متنی بنویسید که با کاما از هم جدا شده باشند A={'a','b','c'}; B=randn(100,3); fid=fopen('myFile.csv','wt'); [rows,cols]=size(A) for i=1:rows fprintf(fid,'%s,',A{i,1:end-1}) fprintf(fid,'%s\n',A{i,end}) end dlmwrite(fid,B,'-append'); fclose(fid); بخش بیشتر کد را از این سایت گرفتم: http://www.mathworks.com/matlabcentral/answers/97487 دوست عزیز کد شما خطای زیر رو داره! Error using dlmwrite (line 93) FILENAME must be a string. فک نکنم بشه که با دی ام ال رایت داده های عددی رو در ادامه ی داده های رشته ای رایت (اضافه) کرد! راهی که خودم امتحان کردم تبدیل هر دو به سلولی بودش و سپس رایت آنها به فایل تی ایکس تی

rahnema1
چهارشنبه 13 فروردین 1393, 10:50 صبح
این یکی را امتحان کنید ببینید میشه اون کد من توی octave امتحان کردم


A={'a','b','c'};
B=randn(100,3);
fid=fopen('myFile.csv','wt');
[rows,cols]=size(A)

for i=1:rows

fprintf(fid,'%s,',A{i,1:end-1})
fprintf(fid,'%s\n',A{i,end})
end

fclose(fid);
dlmwrite('myFile.csv',B,'-append');

در ضمن حالا اینکه csv باشه یا txt فرقی نمی کنه در هر صورت داده ها با کاما جدا میشن پسوندش را خودتون در برنامه یا به صورت دستی می تونید تغییر بدید

hamidkor
چهارشنبه 13 فروردین 1393, 11:00 صبح
این یکی را امتحان کنید ببینید میشه اون کد من توی octave امتحان کردم A={'a','b','c'}; B=randn(100,3); fid=fopen('myFile.csv','wt'); [rows,cols]=size(A) for i=1:rows fprintf(fid,'%s,',A{i,1:end-1}) fprintf(fid,'%s\n',A{i,end}) end fclose(fid); dlmwrite('myFile.csv',B,'-append'); در ضمن حالا اینکه csv باشه یا txt فرقی نمی کنه در هر صورت داده ها با کاما جدا میشن پسوندش را خودتون در برنامه یا به صورت دستی می تونید تغییر بدید فعلا که واسه داده های بالا جواب میده حالا باید رو داده های اصلی امتحان کنم و امیدوارم مشکل حافظه و زمان بوجود نیاد. بازم بابت راهنمایی ارزندتون سپاسمندم، قسمت دوم کدتون جالب بود! تبریک میگم بهتون بابت توانایی تون.

راستی شاید ربطی به این سایت و بحث هاش نداشته باشه ولی لینکی که از مس ورک گذاشتین رو نمیتونم وارد بشم! میگه که دسترسی محدوده و از این حرفا! راهایی که تو نت پیشنهاد شده بود هم رفتم ولی باز به مشکل میخوره! کنجکاو بودم این سایت رو زیارت کنم!!!!!!!!!!

niloofar_f
چهارشنبه 13 فروردین 1393, 11:18 صبح
راستی شاید ربطی به این سایت و بحث هاش نداشته باشه ولی لینکی که از مس ورک گذاشتین رو نمیتونم وارد بشم! میگه که دسترسی محدوده و از این حرفا! راهایی که تو نت پیشنهاد شده بود هم رفتم ولی باز به مشکل میخوره! کنجکاو بودم این سایت رو زیارت کنم!!!!!!!!!!

از ف ی ل ت ر شکن اسفاده کنید!!!

rahnema1
چهارشنبه 13 فروردین 1393, 11:20 صبح
یک راه دیگه آدرس را در yahoo وارد کنید سپس از cache اون وارد سایت بشید

hamidkor
چهارشنبه 13 فروردین 1393, 14:20 عصر
باسلام،
دوستای گرام فک کردم مشکل حل شد، اما وقتی خواستم تو ابعاد بزرگتر اجرا کنم به مشکل جدیدی برخوردم! اونم به این صورت هستش که تو ابعاد بالا ما مجبوریم عنوان ستون ها که بصورت رشته ای هستند رو بصورت خودکار در متلب تولید کنیم بجای اینکه دستی در مقیاس پائین وارد کنیم و برای اینکار در حالتی که بخواهیم از تبدیل به کلاس سلولی استفاده کنیم باید از توابع استفاده کنیم و رایت آنها تو یه فایل متنی بصورت زیر امکان پذیر هستش ...
coordtxt={'X';'y';'z'};
coordtxt=cellstr(coordtxt)';
dtmhdlblkmdl=cellfun(@(x) sprintf('BM%d',x),num2cell(1:100),'Un',0);
dtmhdlblkmdld=cellfun(@(x) sprintf('Density%d',x),num2cell(1:100),'Un',0);
finaldtmhdltxtblkmdl=[coordtxt,dtmhdlblkmdl,dtmhdlblkmdld];
% output filename
outfile = 'BlockModel(dtm)';
filename = [outfile,'.txt'];
% initialize/open the file
fid = fopen(filename,'w');
% write each cell to the text file
[nrows,ncols]= size(finaldtmhdltxtblkmdl);
for row=1:nrows
fprintf(fid,'%s ',finaldtmhdltxtblkmdl{row,:});
end

نکته ی دیگر اینکه خروجی این فایل به عنوان ورودی یه نرم افزار دیگه ایه که داده ها در آن مثل اکسل لود میشن و اگر خروجی کد بالا رو با اکسل لود کنیم هر سلول تو یه سلول اکسل جداگانه قابل تفکیک هستش اما این کد رو ادامه بدیم و داده های عددی رو به ادامه ی فایل متنی اضاف کنیم (با دی ام ال رایت ی که پیشنهاد شد) سپس تو لود کردن داده ها به مشکل میخوریم و هر عنوان روی هر ستون قرار نمیگره! و همه ی عناوین که بصورت رشته ای هستن تو اولین ستون اکسل جای میگیرن!
B=rand(10,200,'single');
dlmwrite('BlockModel(dtm).txt',B,'-append');

اگر بشه که عناوین که بصورت ترکیب حروف و اعداد (Density1 Density2 Density3 ... Density100 BM1 BM2 BM3 ... BM100 ) هستن رو بصورت رشته ای مرتب تولید کرد اون موقع میشه با روش پیشنهادی (dlmwrite) قسمت اصلی که ماتریس عددی یه میلیون در دویست هستش رو به ادامه فایل متنی اضاف نمود.

rahnema1
چهارشنبه 13 فروردین 1393, 14:47 عصر
توی کد شما به جای کاما اسپیس میذاره که تبدیل به کاما کردم بعد از این ها دستور dlmwrite را بذارید

coordtxt={'X';'y';'z'};
coordtxt=cellstr(coordtxt)';
dtmhdlblkmdl=cellfun(@(x) sprintf('BM%d',x),num2cell(1:100),'Un',0);
dtmhdlblkmdld=cellfun(@(x) sprintf('Density%d',x),num2cell(1:99),'Un',0);
finaldtmhdltxtblkmdl=[coordtxt,dtmhdlblkmdl,dtmhdlblkmdld];
% output filename
outfile = 'BlockModel(dtm)';
filename = [outfile,'.txt'];
% initialize/open the file
fid = fopen(filename,'w');
% write each cell to the text file
[nrows,ncols]= size(finaldtmhdltxtblkmdl);
for row=1:nrows
fprintf(fid,'%s,',finaldtmhdltxtblkmdl{row,:});
end
fprintf(fid,'%s\n','Density100')
fclose(fid)

hamidkor
چهارشنبه 13 فروردین 1393, 16:18 عصر
توی کد شما به جای کاما اسپیس میذاره که تبدیل به کاما کردم بعد از این ها دستور dlmwrite را بذارید

coordtxt={'X';'y';'z'};
coordtxt=cellstr(coordtxt)';
dtmhdlblkmdl=cellfun(@(x) sprintf('BM%d',x),num2cell(1:100),'Un',0);
dtmhdlblkmdld=cellfun(@(x) sprintf('Density%d',x),num2cell(1:99),'Un',0);
finaldtmhdltxtblkmdl=[coordtxt,dtmhdlblkmdl,dtmhdlblkmdld];
% output filename
outfile = 'BlockModel(dtm)';
filename = [outfile,'.txt'];
% initialize/open the file
fid = fopen(filename,'w');
% write each cell to the text file
[nrows,ncols]= size(finaldtmhdltxtblkmdl);
for row=1:nrows
fprintf(fid,'%s,',finaldtmhdltxtblkmdl{row,:});
end
fprintf(fid,'%s\n','Density100')
fclose(fid)


ممنون دوست عزیز واقعا لطف کردین، مشکل برطرف شد و تو 366 ثانیه با ماتریس اصلی خروجی میده! شاید زمان یه خورده زیاد باشه واسه رایت ولی همین که امکان پذیر شدش جای تقدیر از جنابعالی رو داره. بازم از لطفتتون سپاسمندم