Python结构化数组不起作用

时间:2017-02-05 13:45:47

标签: python pandas numpy structured-array

我通过使用熊猫的整数,浮点数和字符串,通过Anaconda的Spyder(Python 2)中的IPython控制台导入153,673*25 csv数据矩阵。然后,我想通过pandaframe列名称和手动类型指定列名称,将此数据转换为结构化数组。以下是代码 - 函数importing_data.run()attributes_names.run()分别以pandaframe格式导入csv数据,并将pandaframe的列名称作为列表提取:

import pandas
import numpy
import importing_data
import attributes_names

csv_data    = importing_data.run()
names       = attributes_names.run(csv_data)

type_list   = ['int',
               'str',
               'str',
                ...
               'float',
               'int',
               'int',
              ]

data_type   = zip(names,type_list)

n_rows      = len(csv_data.ix[:,0])
n_columns   = len(csv_data.ix[0,:])
data_sample = numpy.zeros((n_rows,n_columns),dtype=data_type)

for i in range(0,n_columns):
    column              = csv_data.ix[:,i].values
    data_sample[:,i]    = column

然而,最终的循环似乎失败了:它有时会推动内核重新启动,而当它没有时,data_sample数组会有意想不到的结构;我不能准确地描述它,因为我最近只有内核重启,但我相信它是由153,673*25维列表组成的153,673维数组。

我在这里做错了什么?

修改

我犯的第一个错误如下:而不是

data_sample = numpy.zeros((n_rows,n_columns),dtype=data_type)

我必须把:

data_sample = numpy.zeros((n_rows,1),dtype=data_type)

我已按如下方式重新定义循环:

for i in range(0,n_rows):
    data_sample[i,0] = csv_data.values[i,:]

但现在我收到以下错误消息:TypeError: expected a single-segment buffer object

1 个答案:

答案 0 :(得分:0)

在没有熊猫并发症的情况下重建你的问题:

In [695]: names=['a','b','c']
In [696]: type_list=['int','float','int']
In [697]: datatype=list(zip(names,type_list))
In [698]: dt = np.dtype(datatype)
In [699]: dt
Out[699]: dtype([('a', '<i4'), ('b', '<f8'), ('c', '<i4')])

制作data数组lilke csv_data.values。因为你期待字符串和数字我怀疑这是一个对象dtype数组(pandas经常转向那个dtype)

In [712]: data = np.arange(12).reshape(4,3).astype(object)
In [713]: data
Out[713]: 
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8],
       [9, 10, 11]], dtype=object)

创建目标结构化数组。注意它是1d,4个元素(行/记录),有3个字段(来自dtype)

In [714]: A = np.zeros((4,), dtype=dt)
In [715]: A
Out[715]: 
array([(0,  0., 0), (0,  0., 0), (0,  0., 0), (0,  0., 0)], 
      dtype=[('a', '<i4'), ('b', '<f8'), ('c', '<i4')])

结构化数组的输入应该是元组或元组列表

In [716]: for i in range(4):
     ...:     A[i] = tuple(data[i,:])

In [717]: A
Out[717]: 
array([(0,   1.,  2), (3,   4.,  5), (6,   7.,  8), (9,  10., 11)], 
      dtype=[('a', '<i4'), ('b', '<f8'), ('c', '<i4')])

分配列表有效,但存储意外值。我怀疑它是在做字节副本,而没有注意dtype。

In [718]: for i in range(4):
     ...:     A[i] = data[i,:]

In [719]: A
Out[719]: 
array([(139402288,   1.17777468e-268, 0),
       (139402336,   1.17780241e-268, 0),
       (139402384,   1.17783014e-268, 0), (139402432,   1.17785787e-268, 0)], 
      dtype=[('a', '<i4'), ('b', '<f8'), ('c', '<i4')])

我也可以直接创建A,数据是元组列表

In [720]: d = [tuple(r) for r in data]
In [721]: d
Out[721]: [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)]
In [722]: A=np.array(d, dtype=dt)
In [723]: A
Out[723]: 
array([(0,   1.,  2), (3,   4.,  5), (6,   7.,  8), (9,  10., 11)], 
      dtype=[('a', '<i4'), ('b', '<f8'), ('c', '<i4')])

您还可以按字段名称指定值。通常这会更快,因为通常有多行而不是字段

In [725]: for i,n in enumerate(dt.names):
     ...:     print(i,n)
     ...:     A[n] = data[:,i]
     ...:     
0 a
1 b
2 c
In [726]: A
Out[726]: 
array([(0,   1.,  2), (3,   4.,  5), (6,   7.,  8), (9,  10., 11)], 
      dtype=[('a', '<i4'), ('b', '<f8'), ('c', '<i4')])