0

我正在153,673*25通过 Anaconda 的 Spyder(Python 2)中的 IPython 控制台使用 pandas 导入一个包含整数、浮点数和字符串的 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

4

1 回答 1

0

在没有所有 pandas 并发症的情况下重建您的问题:

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 数组(熊猫经常使用该 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')])
于 2017-02-05T17:38:49.733 回答