首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将NumPy数组元素从字符串更改为整型或浮点型?

如何将NumPy数组元素从字符串更改为整型或浮点型?
EN

Stack Overflow用户
提问于 2015-07-19 19:57:29
回答 3查看 7.3K关注 0票数 2

我有一个存储在NumPy数组中的数据集,如下所示,但其中的所有数据都存储为字符串。如何将字符串更改为intfloat,并将其存储在后台?

代码语言:javascript
复制
  data = numpy.array([]) # <--- array initialized with numpy.array

data变量中,存储了以下信息

代码语言:javascript
复制
 [['1' '0' '3' ..., '7.25' '' 'S']
  ['2' '1' '1' ..., '71.2833' 'C85' 'C']
   ['3' '1' '3' ..., '7.925' '' 'S']
   ..., 
   ['889' '0' '3' ..., '23.45' '' 'S']
   ['890' '1' '1' ..., '30' 'C148' 'C']
   ['891' '0' '3' ..., '7.75' '' 'Q']]

我想将第一列更改为int,并将值存储回去。为了做到这一点,我做到了:

代码语言:javascript
复制
 data[0::,0] = data[0::,0].astype(int)

但是,这并没有改变任何事情。

EN

Stack Overflow用户

发布于 2015-07-20 02:25:23

我可以从字符串列表开始创建一个包含字符串的数组;请注意S4数据类型:

代码语言:javascript
复制
In [690]: data=np.array([['1','0','7.23','two'],['2','3','1.32','four']])

In [691]: data
Out[691]: 
array([['1', '0', '7.23', 'two'],
       ['2', '3', '1.32', 'four']], 
      dtype='|S4')

这样的数组更有可能是通过读取csv文件创建的。

我还可以将其视为单字节字符串数组-形状和数据类型已更改,但databuffer是相同的(相同的32字节)

代码语言:javascript
复制
In [692]: data.view('S1')
Out[692]: 
array([['1', '', '', '', '0', '', '', '', '7', '.', '2', '3', 't', 'w',
        'o', ''],
       ['2', '', '', '', '3', '', '', '', '1', '.', '3', '2', 'f', 'o',
        'u', 'r']], 
      dtype='|S1')

实际上,我可以更改单个字节,将原始数组的two更改为twos

代码语言:javascript
复制
In [693]: data.view('S1')[0,-1]='s'

In [694]: data
Out[694]: 
array([['1', '0', '7.23', 'twos'],
       ['2', '3', '1.32', 'four']], 
      dtype='|S4')

但是,如果我尝试将data的元素更改为整数,它将被转换为与S4数据类型匹配的字符串:

代码语言:javascript
复制
In [695]: data[1,0]=4

In [696]: data
Out[696]: 
array([['1', '0', '7.23', 'twos'],
       ['4', '3', '1.32', 'four']], 
      dtype='|S4')

如果数字来自int(data[1,0])或它的一些变体,也会发生同样的情况。

但是我可以欺骗它将整数看作一个字节字符串(表示为\x04)

代码语言:javascript
复制
In [704]: data[1,0]=np.array(4).view('S4')

In [705]: data
Out[705]: 
array([['1', '0', '7.23', 'twos'],
       ['\x04', '3', '1.32', 'four']], 
      dtype='|S4')

数组可以共享数据缓冲区。data属性是指向内存块的指针。该数组的dtype控制如何解释该块。例如,我可以创建另一个it数组,然后重定向它的data属性:

代码语言:javascript
复制
In [714]: d2=np.zeros((2,4),dtype=int)

In [715]: d2
Out[715]: 
array([[0, 0, 0, 0],
       [0, 0, 0, 0]])

In [716]: d2.data=data.data  # change the data pointer

In [717]: d2
Out[717]: 
array([[        49,         48,  858926647, 1936684916],
       [         4,         51,  842214961, 1920298854]])

现在d2[1,0]是整数4。但是其他的项是无法识别的,因为它们是被视为整数的字符串。这与通过int()函数传递它们不同。

我不建议像这样经常更改data指针。这很容易把事情搞砸。我必须小心确保d2.nbytes为32,与data相同。

因为缓冲区是分片的,所以对d2的更改也会出现在data中(但根据不同的数据类型显示):

代码语言:javascript
复制
In [718]: d2[0,0]=3

In [719]: data
Out[719]: 
array([['\x03', '0', '7.23', 'twos'],
       ['\x04', '3', '1.32', 'four']], 
      dtype='|S4')

具有复杂数据类型的视图执行类似的操作:

代码语言:javascript
复制
In [723]: data.view('i4,i4,f,|S4')
Out[723]: 
array([[(3, 48, 4.148588672592268e-08, 'twos')],
       [(4, 51, 1.042967401332362e-08, 'four')]], 
      dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<f4'), ('f3', 'S4')])

注意也出现在d2中的4851。下一个float列无法识别。

这给出了一个想法,什么可以和不能做的“就地”。

但是要获得一个包含有意义的数字和字符串的数组,i最好构造一个新的结构化数组。也许最干净的方法是使用一个中间的元组列表。

代码语言:javascript
复制
In [759]: dl=[tuple(i) for i in data.tolist()]

In [760]: dl
Out[760]: [('1', '0', '7.23', 'two'), ('2', '3', '1.32', 'four')]

In [761]: np.array(dl,dtype='i4,i4,f,|S4')
Out[761]: 
array([(1, 0, 7.230000019073486, 'two'), (2, 3, 1.3200000524520874, 'four')], 
      dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<f4'), ('f3', 'S4')])

所有这些字段都占用4个字节,因此nbytes是相同的。但是各个值都通过了转换器。我已经给了'np.array‘自由转换值的自由,因为这对于输入和新的数据类型是一致的。这比尝试执行某种复杂的就地转换要容易得多。

一个混合了数字和字符串的列表元组也可以工作:

代码语言:javascript
复制
[(1, 0, 7.23, 'two'), (2, 3, 1.32, 'four')]

结构化数组以元组列表的形式显示。在结构化数组文档中,值总是以元组列表的形式输入。

也可以使用recarray,但本质上这只是一个数组子类,允许您将字段作为属性进行访问。

如果原始数组是从csv文件生成的,最好使用带有适当选项的np.genfromtxt (或loadtxt)。它可以生成适当的元组列表,并直接返回结构化数组。

票数 1
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31500939

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档