python——不同数据结构相互转换:数组、列表、字符串、Tensor等
数组与其他类型相互转换
数组与列表互转(np.array与list)
- 数组转列表(arr转list):np.array(a)
- 列表转数组(list转arr):a.tolist()
import numpy as np
a=[1,2,3,4]
print(f"a的类型{type(a)}")
a_arr = np.array(a)
print(f"a_arr的类型{type(a_arr)}")
a_list=a_arr.tolist()
print(f"a_list的类型{type(a_list)}")
a的类型<class 'list'>
a_arr的类型<class 'numpy.ndarray'>
a_list的类型<class 'list'>
数组与字符串互转(np.arr与str)
数组转字符串(arr转str)
1.数组中存放的是字符串,使用join直接将数组中的元素直接拼接起来
import numpy as np
a = np.array(['a','b','c','d'])
s1 = ''.join(a)
s2 = ' '.join(a)
s3 = ','.join(a)
s4 = ''.join(x for x in a)
print(f's1={s1},s2={s2},s3={s3},s4={s4}')
s1=abcd,s2=a b c d,s3=a,b,c,d,s4=abcd
2.数组中存放的是数字,先将数字转为str再使用join进行拼接
a = np.array([1,2,3,4])
s1 = ''.join(str(x) for x in a)
s2 = ' '.join(str(x) for x in a)
s3 = ','.join(str(x) for x in a)
print(f'数组a={a}')
print(f's1={s1},s2={s2},s3={s3}')
s4 = ''.join(str(a))
print(f's4={s4}')
数组a=[1 2 3 4]
s1=1234,s2=1 2 3 4,s3=1,2,3,4
s4=[1 2 3 4]
''符号表示使用空字符拼接,就是无缝拼接,拼接结果为ab,也可根据实际情况使用','拼接,结果就是a,b 根据实际灵活运用~
字符串转数组(str转arr):要先转list,再转为arr
- 通过str的split函数实现str转list,再用np.array(a)转为数组,split()参数为空时,默认以空格来做分割
a = 'abc'
b = 'hello good boy'
c = 'a,b c,d'
out1 = list(a) #直接通过list转换,是以每个字符进行分割
out2 = b.split() #参数为空,默认以空格为分割
out3 = c.split(',') #以逗号为分割
print(out1)
print(out2)
print(out3)
['a', 'b', 'c']
['hello', 'good', 'boy']
['a', 'b c', 'd']
数组与pytorch.Tensor互转
numpy.ndarray与torch.tensor
1.打印数据类型的方式也有区别,numpy中没有x.type()的用法,只能使用type(x)
2.numpy.ndarray类型的数据只能放在cpu中计算,而tensor可以放在GPU计算,也可以CPU计算
数组转tensor
有4中转换方法,分为深拷贝和浅拷贝方法,浅拷贝是直接共享内存内存空间的,这样效率更高,而深拷贝是直接创建一个新的副本
import torch
import numpy as np
arr1 = np.array([1,2,3], dtype=np.float32)
arr2 = np.array([4,5,6])
print(arr1.dtype)
print("numpy中array的默认数据类型为:", arr2.dtype)
tensor = torch.tensor(arr2)
Tensor = torch.Tensor(arr2)#torch.Tensor()是torch.FloatTensor()的简写
as_tensor = torch.as_tensor(arr2)
from_numpy = torch.from_numpy(arr2)
print(tensor.dtype, "|",Tensor.dtype, "|",as_tensor.dtype, "|",from_numpy.dtype)
arr2[0] = 100 #改变arr2的值,tensor和Tensor不变,as_tensor,from_numpy随着改变,得到下方小结中的结论
print(tensor, Tensor, as_tensor, from_numpy)
float32
numpy中array的默认数据类型为: int32
torch.int32 | torch.float32 | torch.int32 | torch.int32
tensor([4, 5, 6], dtype=torch.int32) tensor([4., 5., 6.]) tensor([100, 5, 6], dtype=torch.int32) tensor([100, 5, 6], dtype=torch.int32)
小结:numpy中array默认的数据格式是int32(有的版本是int64)类型,torch中tensor默认的数据格式是float32类型(torch.Tensor()是torch.FloatTensor()的缩写,所以float32实际是FloatTensor强制转化得到的浮点型数据)。as_tensor和from_numpy是浅拷贝,而tensor和Tensor则是属于深拷贝,浅拷贝是直接共享内存内存空间的,这样效率更高,而深拷贝是直接创建一个新的副本
此部分示例代码参考了这个博客,点击此处
使用torch.tensor()建立tensor数据的时候可以通过torch.set_default_tensor_type(t)设置默认的tensor类型,如要使用torch.tensor()建立一个双精度浮点类型的张量,如下所示:
>>> torch.set_default_tensor_type(torch.DoubleTensor) #指定默认类型
>>> torch.tensor([1.2, 3]).dtype
torch.float64
tensor转数组
有两个方法
import torch
x = torch.ones(5) # 创建张量x=tensor([1., 1., 1., 1., 1.])
x_arr = x.detach().numpy() # 方法一 :x_arr=[1. 1. 1. 1. 1.]
x_arr1 = x.numpy() # 方法二:x_arr1=[1. 1. 1. 1. 1.]
x_arr1[0] = 22
print(x) # tensor([22., 1., 1., 1., 1.])
print(x_arr)# [22. 1. 1. 1. 1.]
改变x_arr1的值,x和x_arr的值也随着改变,说明tensor转数组也是内存共享的
上述两个方法在于是否使用detach(),要是转换前的tensor在原来的计算图中计算梯度了,那么就需要使用detach(),表示得到的新变量不计算梯度,否则会报错,如下:
未使用detach(),报错
import torch
x = torch.ones([5], requires_grad = True)
y = x.numpy()
print(y)
Traceback (most recent call last):
File "c:\Users\11922\Desktop\lung-project\code\Dataprocess\数据转换.py", line 3, in <module>
y = x.numpy()
RuntimeError: Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead.
使用detach(),不报错
import torch
x = torch.ones([5], requires_grad = True)
y = x.detach().numpy()
print(y) #[1. 1. 1. 1. 1.]
gpu上的tensor不能直接转为numpy,要先转到cpu
ndarray = tensor.cpu().numpy()
列表与其他类型互转
列表与数组互转(见数组与其他类型)
列表与字符串互转
列表转字符串(与数组转字符串相同)
字符串转列表(见字符串转数组)
字符串转数组先,需要先转为列表
列表与Tensor互转
列表转Tensor(list转tensor)
与list转arr相同,可指定转换后的类型
import torch
a = [1, 2, 3]
print(' type :{0} value: {1}'.format(type(a), a))
tensor = torch.Tensor(a) #是torch.FloatTensor的缩写,默认为float
print(' type :{0} value: {1}'.format(type(tensor), tensor))
tensor = torch.IntTensor(a) #转为int
print(' type :{0} value: {1}'.format(type(tensor), tensor))
type :<class 'list'> value: [1, 2, 3]
type :<class 'torch.Tensor'> value: tensor([1., 2., 3.])
type :<class 'torch.Tensor'> value: tensor([1, 2, 3], dtype=torch.int32)
——————————————————————————————————————————————
踩坑历史:2024.6.12,list转Tensor报错
原因:要转换的list里面的元素包含多维的tensor。
- 一般list 转 torch.tensor只需要
tensor=torch.tensor(list)
- 但是要转换的list里面的元素包含多维的tensor,应该使用
tensor= torch.tensor([item.cpu().detach().numpy() for item in list).cuda()
这是由于 gpu上的 tensor 不能直接转为 numpy; 须要先在 cpu 上完成操做,再回到 gpu 上 - 也可使用
tensor=torch.stack(list)
函数堆叠,默认在dim=0的维度堆叠
——————————————————————————————————————————————
tensor转list
需要先转numpy,再用a.tolist()转为list
import torch
tensor = torch.Tensor([1, 2, 3])
print(' type :{0} value: {1}'.format(type(tensor), tensor))
list = tensor.numpy().tolist()
print(' type :{0} value: {1}'.format(type(list), list))
type :<class 'torch.Tensor'> value: tensor([1., 2., 3.])
type :<class 'list'> value: [1.0, 2.0, 3.0]