规范化/标准化numpy重新排列

Ano*_*sse 7 python numpy normalize scipy recarray

我想知道正常化/标准化numpy的最佳方法是什么recarray.为了说清楚,我不是在谈论一个数学矩阵,而是一个记录数组,它也有例如文本列(如标签).

a = np.genfromtxt("iris.csv", delimiter=",", dtype=None)
print a.shape
> (150,)
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我无法进行处理,a[:,:-1]因为形状是一维的.

我找到的最好的是迭代所有列:

for nam in a.dtype.names[:-1]:
    col = a[nam]
    a[nam] = (col - col.min()) / (col.max() - col.min())
Run Code Online (Sandbox Code Playgroud)

这样做更优雅的方式?是否有某些方法,如"标准化"或"标准化"?

Joe*_*ton 7

有很多方法可以做到,但有些方法比其他方法更清洁.

通常,在numpy中,将字符串数据保存在单独的数组中.

(事情比R的数据框架要低一些.你通常只是在一个类中包装用于关联,但是将不同的数据类型分开.)

老实说,numpy没有针对处理这种"灵活"数据类型进行优化(虽然它当然可以做到).像pandas为电子表格一样的数据提供了更好的界面(而熊猫只是numpy之上的一层).

但是,当您传入字段名称列表时,结构化数组(这是您在此处拥有的)将允许您按列进行切片.(例如data[['col1', 'col2', 'col3']])

无论如何,一种方法是做这样的事情:

import numpy as np

data = np.recfromcsv('iris.csv')

# In this case, it's just all but the last, but we could be more general
# This must be a list and not a tuple, though.
float_fields = list(data.dtype.names[:-1])

float_dat = data[float_fields]

# Now we just need to view it as a "regular" 2D array...
float_dat = float_dat.view(np.float).reshape((data.size, -1))

# And we can normalize columns as usual.
normalized = (float_dat - float_dat.min(axis=0)) / float_dat.ptp(axis=0)
Run Code Online (Sandbox Code Playgroud)

然而,这远非理想.如果你想就地进行操作(就像你现在的那样),最简单的解决方案就是你已经拥有的:只需迭代字段名称即可.

顺便说一句,使用pandas,你会做这样的事情:

import pandas
data = pandas.read_csv('iris.csv', header=None)

float_dat = data[data.columns[:-1]]
dmin, dmax = float_dat.min(axis=0), float_dat.max(axis=0)

data[data.columns[:-1]] = (float_dat - dmin) / (dmax - dmin)
Run Code Online (Sandbox Code Playgroud)