When you time series analysis, your input is presumably already numerical, so the notion of an embedding is not an issues there.
In NLP you typically deal with words, i.e., non-numerical input. So you have to encode your sentences, paragraphs, documents, etc. somehow for the model to “understand” them. The naive approach would be to One-Hot encoding where each word is a vector of the size of your vocabulary with only a single 1 at the index of the corresponding word. For example if the index of word “hello” has the index 42 in your vocabulary, the One-Hot encoded word vector for “hello” would look like:
[0 0 0 0 0 ... 0 0 1 0 ... 0 0 0 0 0 0 ]

with the whole vector being vocab_size long, and the 1 is at index 42. The problem is that for many NLP applications, your vocabulary can be very large, e.g., way beyond 100,000 words (but let’s stick with 100k). Now, if your input document has, say 100 words, then your input for your model is a M.shape = (100, 100000). This is annoyingly large…and unnecessarily so, as we see in a bit…
Your first layer getting this input is typically an Linear layer of, say, shape E.shape = (100000, 300) to reduce the dimensionality. If you do the calculations, you will notice that M.dot(E) does nothing more than selecting the rows in E that correspond to the indices of the 1’s in M (because M is One-Hot encoded). If this is unclear, I recommend doing this with a toy example on paper.
Knowing this, there’s no need for the One-Hot encoded matrix M anymore, we only need the indices of the words. nn.Embedding is more or less just a linear layer to facilitate the M.dot(E) but without the need of the large matrix M. This is why you don’t see any example in NLP without an explicit embedding layer (an exception might be character-based models where you vocabulary is small, e.g., < 100 characters).