I have several sets of 20 images I need to import.

enter image description here

Each time they have different categories.


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_] := 
  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 :

enter image description here

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.

  • $\begingroup$ As in "How do I import them and let Mathematica do the categorization based on the filename"? $\endgroup$
    – David
    Feb 1, 2012 at 19:06
  • $\begingroup$ @David yes :-) I remember someone showed a trick to import all files which name start with ... in a question that was closed and he removed his answer... $\endgroup$
    – 500
    Feb 1, 2012 at 19:18

3 Answers 3


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.


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:

   Export[#, "Test" <> ToString[#2], "Text"] &,
       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}"}}

  • $\begingroup$ Thank You very much for the detailed explanation. $\endgroup$
    – 500
    Feb 2, 2012 at 1:46
  • $\begingroup$ @500 No problem - glad I could help. $\endgroup$ Feb 2, 2012 at 1:47

Here is one approach. First set your working directory with SetDirectory, then:

names = FileNames["*.png"];

groups = GatherBy[names, StringTake[#, {-6}] &];

   electric[StringTake[#, {-6}]] & /@ groups[[All, 1]]
] = Map[Import[#] ~ImageResize~ 128 &, groups, {2}];

Now access image lists like:


This relies on manually picking a string position to index by, here {-6}. Leonid's method would be more robust for future naming.

  • $\begingroup$ Thank You, I must say evaluate remains quite mysterious to me yet :-) $\endgroup$
    – 500
    Feb 2, 2012 at 2:07
  • $\begingroup$ @500 Evaluate is used when you need something to evaluate first, so that a function does not see the unevaluated form. In this case, I needed Set (=) not to see electric[StringTake[#, {-6}]] ... but instead see {electric["B"], electric["C"] ...}. $\endgroup$
    – Mr.Wizard
    Feb 2, 2012 at 3:17

This is how you import all files satisfying a certain pattern:

1. Import the directory. This will give you a list of all the files it contains.

fileList = Import[NotebookDirectory[] <> "/pics"]
{"fooA1bar.png", "fooA2bar.png", "fooA3bar.png", "fooBbar.png"}

2. For convenience, define a function that returns TRUE if the argument starts with a certain string. I use a string pattern here for simplicity. (Regex would be the normal way for me, but people complained in other questions.)

startsWithQ[string_, start_] := StringMatchQ[
    start ~~ ___

3. You can now use this function to create another function that extracts all the files starting with some string from the original file list (i.e. the list you obtained by importing the directory).

filterFileList[startsWith_] := Select[
    startsWithQ[#, startsWith] &

4. Apply that function! :-)

{"fooA1bar.png", "fooA2bar.png", "fooA3bar.png"}

As you can see, only the files starting with fooA remain. This method does of course work with other string patterns (or regular expressions), simply replace the pattern ("start ~~ ___") according to your needs.

5. Import the pictures by applying Import to every list element and your're done:

getPictures[filelist_] := Import[picpath <> "/" <> #] & /@ filelist

enter image description here

As mentioned by Spartacus, you could also use FileNames to get around many of the steps above. On the other hand, using patterns is much more flexible, and can match quite complicated filenames effectively.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.