I have several sets of 20 images I need to import.
Each time they have different categories.
"Name"<>"Cat"<>"No"
Electric B 1 for example.
I need to create lists that contain the images for those different categories.
As of now this is what i am doing :
importOne[set_, cat_, num_] :=
ImageResize[
Import[FileNameJoin[{NotebookDirectory[], set,
set <> cat <> ToString[num] <> ".png"}]], 128]
ElectricB = importOne["Electric", "B", #] & /@ Range[6];
ElectricC = importOne["Electric", "C", #] & /@ Range[5];
ElectricN = importOne["Electric", "N", #] & /@ Range[5];
ElectricE = importOne["Electric", "E", #] & /@ Range[4];
And then, thanks to previous question/answers :
What would be a more efficient mean to import automatically for different sets ?
As of now I need to repeat this operation for each set.
Answer
Make your filenames unambiguously parsable, e.g. by consistently using some delimeters like underscores or something. A typical file name can look like "Electric_B_3.png"
. EDIT If you have no control over the file names, use string patterns as described by other answers, but in the long-term you may benefit from creating your own robust naming scheme END EDIT
Then write a function that would parse a single file name, something like:
fileNameParse[fname_String, delim_String: "_"] :=
StringSplit[FileBaseName[fname], delim]
Then, Map
it on FileNames["*.png", {your-dir}]
.
Finally, apply your importOne
on the level one:
importOne@@@Map[fileNameParse, FileNames["*.png", {your-dir}]]
Since you have the result of Map
available as well, you can regroup them any way you want. You can, for example, Map
a function {#, importOne@@#}&
, rather than just using importOne@@@...
. Then, you could use GatherBy
or any other means to regroup and collect your images according to the parts of their filenames.
EDIT
Here is a self-contained example ( I use text files, but this doesn't matter):
ClearAll[fileNameParse, fileNameMake, importOne, $dir];
fileNameParse[fname_String, delim_String: "_"] :=
StringSplit[FileBaseName[fname], delim];
fileNameMake[pieces_List, delim_String: "_", ext_String: ".txt"] :=
StringJoin[Append[Riffle[pieces, "_"], ".txt"]];
importOne[set_, cat_, num_, dir_: $dir] :=
Import[FileNameJoin[{dir, fileNameMake[{set, cat, num}]}]];
We now create a temporary directory:
$dir = FileNameJoin[{$TemporaryDirectory, "ImportTest"}];
If[! FileExistsQ[$dir], CreateDirectory[$dir]];
Create sample files:
MapIndexed[
Export[#, "Test" <> ToString[#2], "Text"] &,
Flatten[
Outer[
FileNameJoin[{$dir, fileNameMake[{##}]}] &,
{"Electric"}, {"A", "B", "C"}, {"1", "2", "3"}
]]];
import them:
imported = Map[{#, importOne @@ #} &, fileNameParse /@ FileNames["*.txt", {$dir}]]
(*
==>
{{{"Electric", "A", "1"}, "Test{1}"}, {{"Electric", "A", "2"}, "Test{2}"},
{{"Electric", "A", "3"}, "Test{3}"}, {{"Electric", "B", "1"}, "Test{4}"},
{{"Electric", "B", "2"}, "Test{5}"}, {{"Electric", "B", "3"}, "Test{6}"},
{{"Electric", "C", "1"}, "Test{7}"}, {{"Electric", "C", "2"}, "Test{8}"},
{{"Electric", "C", "3"}, "Test{9}"}
}
*)
You can now, for example, group them according to whatever parts of their file names you wish:
GatherBy[imported , #[[1, 2]] &][[1]]
(*
==>
{{{"Electric", "A", "1"}, "Test{1}"}, {{"Electric", "A", "2"}, "Test{2}"},
{{"Electric", "A", "3"}, "Test{3}"}}
*)
Comments
Post a Comment