How to turn a list of tensor to tensor?

I have a list and there are many tensor in the list
I want to turn it to just tensor, and I can put it to dataloader

I use for loop and cat the tensor but it is very slow, data size is about 4,800,000

15 Likes

If they’re all the same size, then you could torch.unsqueeze them in dimension 0 and then torch.cat the results together.

12 Likes
a = []
for i in range(100000):
    a.append(torch.rand(1, 100, 100)

b = torch.Tensor(100000, 100, 100)
torch.cat(a, out=b)
20 Likes

I was always doing something like:

a = [torch.FloatTensor([1]).view(1, -1), torch.FloatTensor([2]).view(1, -1)]
torch.stack(a)

Gives me:

(0 ,.,.) = 
  1

(1 ,.,.) = 
  2
[torch.FloatTensor of size 2x1x1]
18 Likes

Actually

I have two list

list 1
a = [[tensor 40], [tensor 40], [tensor 40], …] (2400000 tensor in list each tensor size is 40)
b = [[tensor 40], [tensor 40], [tensor 40], …] (2400000 tensor in list each tensor size is 40)

I want to concat a and b to c
c is a tensor and size is torch.Size([4800000, 40])

I use this method to solve my problem
a = torch.stack(a)
b = torch.stack(b)
c = torch.cat((a, b))

Thank you for all your help !

12 Likes

Or you can just torch.stack(a + b)

18 Likes

It works.
Thank you.

This is how it should be done.

a = torch.stack(a) worked for me

19 Likes

To me it’s sort of unintuitive, why wouldn’t using the tensor class work?

torch.tensor([ torch.tensor([i]).repeat(15) for i in range(0,5)])

the list is the same size and it’s really a matrix/tensor already…but somehow only:

torch.stack([ torch.tensor([i]).repeat(15) for i in range(0,5)])
tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
        [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
        [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]])

worked.

Btw, is this this most efficient way to do it in a vectorized way?

3 Likes

check this out but summary use torch.stack if you want to respect the original nesting of the lists (by having a tensor with many indices and dimensions) and incrementally create it. There might be better ways but that works for me.


# %%

import torch

# stack vs cat

# cat "extends" a list in the given dimension e.g. adds more rows or columns

x = torch.randn(2, 3)
print(f'{x.size()}')

# add more rows (thus increasing the dimensionality of the column space to 2 -> 6)
xnew_from_cat = torch.cat((x, x, x), 0)
print(f'{xnew_from_cat.size()}')

# add more columns (thus increasing the dimensionality of the row space to 3 -> 9)
xnew_from_cat = torch.cat((x, x, x), 1)
print(f'{xnew_from_cat.size()}')

print()

# stack serves the same role as append in lists. i.e. it doesn't change the original
# vector space but instead adds a new index to the new tensor, so you retain the ability
# get the original tensor you added to the list by indexing in the new dimension
xnew_from_stack = torch.stack((x, x, x, x), 0)
print(f'{xnew_from_stack.size()}')

xnew_from_stack = torch.stack((x, x, x, x), 1)
print(f'{xnew_from_stack.size()}')

xnew_from_stack = torch.stack((x, x, x, x), 2)
print(f'{xnew_from_stack.size()}')

# default appends at the from
xnew_from_stack = torch.stack((x, x, x, x))
print(f'{xnew_from_stack.size()}')

print('I like to think of xnew_from_stack as a \"tensor list\" that you can pop from the front')

print()

lst = []
print(f'{x.size()}')
for i in range(10):
    x += i  # say we do something with x at iteration i
    lst.append(x)
# lstt = torch.stack([x for _ in range(10)])
lstt = torch.stack(lst)
print(lstt.size())

print()

# lst = []
# print(f'{x.size()}')
# for i in range(10):
#     x += i  # say we do something with x at iteration i
#     for j in range(11):
#         x += j
#         lstx
#     lst.append(x)
# # lstt = torch.stack([x for _ in range(10)])
# lstt = torch.stack(lst)
# print(lstt.size())
4 Likes

Sorry to bother you after all this time.
I have target['a] which is a list of tensors. when I use

torch.unsqueeze(target['a'], 0)

it gives me this error:

TypeError: unsqueeze(): argument ‘input’ (position 1) must be Tensor, not list

what is the correct way to use torch.unsqueeze?

tensorify is the best! :wink: