GVKun编程网logo

在磁盘上保留numpy数组的最佳方法(磁盘的保留空间)

16

想了解在磁盘上保留numpy数组的最佳方法的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于磁盘的保留空间的相关问题,此外,我们还将为您介绍关于numpy学习笔记-numpy数组的常见用法、N

想了解在磁盘上保留numpy数组的最佳方法的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于磁盘的保留空间的相关问题,此外,我们还将为您介绍关于numpy学习笔记 - numpy数组的常见用法、NumPy数组的最小-最大归一化、python numpy数组的numpy数组、python – 花式索引沿多个轴的numpy数组的最佳实践的新知识。

本文目录一览:

在磁盘上保留numpy数组的最佳方法(磁盘的保留空间)

在磁盘上保留numpy数组的最佳方法(磁盘的保留空间)

我正在寻找一种保留大型numpy数组的快速方法。我想将它们以二进制格式保存到磁盘中,然后相对较快地将它们读回到内存中。不幸的是,cPickle不够快。

我找到了numpy.savez和numpy.load。但是奇怪的是,numpy.load将一个npy文件加载到“内存映射”中。这意味着对数组的常规操作确实很慢。例如,这样的事情真的很慢:

#!/usr/bin/pythonimport numpy as np;import time; from tempfile import TemporaryFilen = 10000000;a = np.arange(n)b = np.arange(n) * 10c = np.arange(n) * -0.5file = TemporaryFile()np.savez(file,a = a, b = b, c = c);file.seek(0)t = time.time()z = np.load(file)print "loading time = ", time.time() - tt = time.time()aa = z[''a'']bb = z[''b'']cc = z[''c'']print "assigning time = ", time.time() - t;

更确切地说,第一行会非常快,但是将数组分配给的其余行却很obj慢:

loading time =  0.000220775604248assining time =  2.72940087318

有没有更好的方法来保存numpy数组?理想情况下,我希望能够在一个文件中存储多个数组。

答案1

小编典典

我是hdf5的忠实拥护者,用于存储大型numpy数组。在python中处理hdf5有两种选择:

http://www.pytables.org/

http://www.h5py.org/

两者都旨在有效地处理numpy数组。

numpy学习笔记 - numpy数组的常见用法

numpy学习笔记 - numpy数组的常见用法

# -*- coding: utf-8 -*-
"""
主要记录代码,相关说明采用注释形势,供日常总结、查阅使用,不定时更新。
Created on Mon Aug 20 23:37:26 2018
 
@author: Dev
"""
 
import numpy as np
from datetime import datetime
import random
 
 
对a,b两个列表的相同位的元素进行运算求和:
# 纯Python
def pythonSum(n):
    # 对列表循环计算
    a = [x for x in range(n)]
    b = [x for x in range(n)]
    c = []
    for i in range(len(a)):
        a[i] = i ** 2
        b[i] = i ** 3
        c.append(a[i] +b[i])
    return c

 

# numpy
def numpySum(n):
    # 直接对数组操作
    a = np.arange(n) ** 2
    b = np.arange(n) ** 3
    c = a + b
    return c

 

# 效率比较
size = 1000
# pythonSum()
start = datetime.now()  # 起始时间
c = pythonSum(size)
delta = datetime.now() - start  # pythonSum()的运行时间
print("The last two elements: ", c[-2:])    # 打印最后两个元素,确认准确性
print("PythonSum elapsed time in microseconds: ", delta.microseconds)   # 以微秒为单位显示运行时间
# pythonSum结果

The last two elements: [995007996, 998001000]
PythonSum elapsed time in microseconds: 999

  

# numpySum()
start = datetime.now()
c = numpySum(size)
delta = datetime.now() - start
print("The last two elements: ", c[-2:])
print("NumpySum elapsed time in microseconds: ", delta.microseconds)
# numpySum结果

The last two elements: [995007996 998001000]
NumpySum elapsed time in microseconds: 0

可以看出使用numpy数组的速度超快~

 

numpy数组
a = np.arange(5)
print(a.dtype)
 
 
多维数组
m = np.array([np.arange(2), np.arange(2)])  # 创建一个二维数组
print(m)
 
# 创建元素为0的数组
zeros = np.zeros(10)
zeros_2 = np.zeros((3, 6))  # 元素为0的3*6数组
 
# 创建元素随机(empty)的数组
empty = np.empty((2, 3, 2))
 
# 访问数组元素
a = np.array(([1, 2], [3, 4]))
print(a[0, 0])
print(a[0, 1])
print(a[1, 0])
print(a[1, 1])
 
 
数组元素的数据类型
print(np.float64(42))   # float浮点型
print(np.float(True))
print(np.float(False))
print(np.int8(42.0))    # int整型
print(np.bool(42))  # Boolean布尔型
print(np.bool(0))
print(np.bool(42.0))
 
# 创建数组时定义元素的数据类型
print(np.arange(7, dtype=np.uint16))
print(np.arange(9, dtype=np.float64))
 
 
数据类型转换
# 类型转换时出现的TypeError异常
try:
    print(np.int(42.0 + 1.j))
except TypeError:
    print("TypeError: can''t convert complex to int!")
 
arr = np.array([1, 2, 3, 4, 5])
print(arr.dtype)    # 元素类型
float_arr = arr.astype(np.float64)
print(float_arr.dtype)
 
arr = np.array([3.7, -1.2, -2.6, 0.5, 12.9, 10.1])
print(arr.dtype)
int_arr = arr.astype(np.int32)  # 将float64类型转换为int32类型
 
# 将字符串数组转换为字符型
numeric_string = np.array([''1.25'', ''-9.6'', ''42''], dtype=np.string_)
print(numeric_string.astype(float)) # 再转换为float类型
 
 
字符编码
print(np.arange(7, dtype=''f''))  # float32
print(np.arange(7, dtype=''d''))  # float64
print(np.arange(7, dtype=''D''))  # complex128
print(np.dtype(float))
print(np.dtype(''f''))
print(np.dtype(''d''))
print(np.dtype(''F''))
print(np.dtype(''D''))
print(np.dtype(''f8''))
print(np.dtype(''float64''))
 
# dtype类的属性
t = np.dtype(''float64'')
print(t.char)   # 字符编码
print(t.type)   # t的类型
print(t.str)
 
 
自定义数据类型
# [(字段1, 类型, 长度), (字段2, 类型, 长度), ...]
t = np.dtype([(''name'', np.str_, 40), (''numitems'', np.int32), (''price'', np.float32)])
print(t)
print(t.name)
itemz = np.array([(''Meaning of life DVD'', 42, 100), (''Butter'', 13, 2.72)])  # 按照格式生成数组
 
 
数组与标量的计算
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr * arr)    # 对应位的元素相乘
print(arr - arr)   # 对应位的元素相减
print(1 / arr)     # 取倒数
print((arr ** 2) ** 0.5)    # 平方后开根号
 
 
一维数组的索引与切片(与列表切片用法相似)
a = np.arange(9)
print(a[3: 7])
print(a[:7:2])  # 从0到6,步长为2
s = slice(3, 7, 2)  # 先设定切片位置及步长,再调用
print(a[s])
print(a[::-1])  # 倒序排列1
s = slice(None, None, -1)   # 倒序排列2
print(a[s])
 
 
多维数组的切片与索引
b = np.arange(24).reshape(2, 3, 4)
print(b.shape)  # 数组b的维数
# 使用索引与切片选取指定元素
print(b[0,0,0])
print(b[:,0,0])
print(b[0])         # 第一维的所有元素
print(b[0, :, :])   # 第一维的所有元素
print(b[0, ...])    # 第一维的所有元素
print(b[0,1])       # 第一维第二行
print(b[0,1,::2])   # 以2为步长
print(b[...,1])     # 两个维的第一列
print(b[:,1])       # 两个维的第一行
print(b[0,:,1])     # 第一维第一列
print(b[0,:,-1])    # 第一维最后一列
print(b[0,::-1, -1])    # 第一维最后一列的倒序排列
print(b[0,::2,-1])  # 第一维的第0行和第2行的最后一个元素
print(b[::-1])      # 两个维倒序
s = slice(None, None, -1)   # 所有元素倒序排列
print(b[(s, s, s)])
 
 
布尔型索引(mask)
names = np.array([''Bob'', ''Joe'', ''Will'', ''Bob'', ''Will'', ''Joe'', ''Joe''])
random.seed(200)    # 设置随机种子
data = np.random.random((7, 4))
 
print(names == ''Bob'')   # 生成布尔型mask
print(data[names == ''Bob'']) # 根据mask的值匹配data数组中的元素
print(data[names == ''Bob'', 2:]) # 匹配值从第三列到最后一列的元素
print(data[names == ''Bob'', 3])  # 匹配值第四列的元素
 
names != ''Bob''
data[~(names == ''Bob'')]
 
mask = (names == ''Bob'') | (names == ''will'') # 或运算符
data[mask]
data[data < 0] = 0
data[names != ''Joe''] = 7
 
花式索引(索引乱序)
arr = np.empty((8, 4))
for i in range(8):
    arr[i] = i
 
arr[[4, 3, 0, 6]]   # 根据索引的顺序取值
arr[[-3, -5, -7]]
arr = np.arange(32).reshape((8, 4))
arr[[1, 5, 7, 2], [0, 3, 1, 2]]
arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]]
arr[np.ix_([1, 5, 7, 2], [0, 3, 1, 2])]
 
 
数组转置
arr = np.arange(15).reshape((3, 5))
arr.reshape((5,3))
print(arr.T)
 
 
改变数据维度
b = np.arange(24).reshape((2, 3, 4))
print(b)
print(b.ravel())    # 将多维数组将为一维
print(b.flatten())
b.shape = (6, 4)
print(b)
print(b.transpose())
b.resize((2, 12))
print(b)
 
注: flatten()与ravel()的区别
# 当修改ravel()返回的值时,会影响原数组;而flatten则不会
arr_a = np.arange(4).reshape(2, 2)
arr_a.ravel()[-1] = 5
print(arr_a)    # arr_a的最后一个元素已被修改
arr_a.flatten()[0] = 10
print(arr_a)    # 不会影响原数组的第一个元素
 
 
组合数组
a = np.arange(9).reshape(3, 3)
print(a)
b = 2 * a
print(b)
# 水平组合
print(np.hstack((a, b)))
print(np.concatenate((a, b), axis=1))
# 竖直组合
print(np.vstack((a, b)))
print(np.concatenate((a, b), axis=0))
# 深度组合deep
print(np.dstack((a, b)))
# column_stack & row_stack(与hstack & vstack效果类似)
oned = np.arange(2)
print(oned)
twice_oned = 2 * oned
print(twice_oned)
print(np.column_stack((oned, twice_oned)))
print(np.column_stack((a, b)) == np.hstack((a, b)))
print(np.row_stack((oned, twice_oned)))
print(np.row_stack((a, b)))
print(np.row_stack((a, b)) == np.vstack((a, b)))
 
 
数组的分割
a = np.arange(9).reshape(3, 3)
print(a)
# 从水平方向分成三列(跨列)
print(np.hsplit(a, 3))
print(np.split(a, 3, axis=1))
# 从竖直方向分成三行(跨行)
print(np.vsplit(a, 3))
print(np.split(a, 3, axis=0))
# 深度分割
c = np.arange(27).reshape(3, 3, 3)
print(c)
print(np.dsplit(c, 3))
 
 
数组的属性
b = np.arange(24).reshape(2, 12)
b.ndim    # 维度
b.size    # 元素个数
b.itemsize    # 单个元素的大小
b.nbytes    # 整个数组的大小(itemsize * size)
# 复数
b = np.array([1.+1.j, 3.+2.j])
b.real    # 实部
b.imag    # 虚部
 
 
数组的转换
b = np.arange(4).reshape(2, 2)
b.flat    # 将数组转换为一维数组
for i in range(len(b.flat)):    # 循环访问数组元素
    print(b.flat[i])
 
b = np.array([1.+1.j, 3.+2.j])
print(b)
print(b.tolist())    # 转换为list
print(b.tostring())    # 转换为字符
# 使用np.fromstring将字符串转换为指定格式
print(np.fromstring(b''\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x08@\x00\x00\x00\x00\x00\x00\x00@'', dtype=complex))
a_t = np.fromstring(''20:42:53'', sep='':'', dtype=int)
print(a_t)
print(a_t.dtype)
 
# 复数转换为整型时会舍弃虚部
print(b.astype(int))
print(b.astype(''complex''))
 

NumPy数组的最小-最大归一化

NumPy数组的最小-最大归一化

我有以下numpy数组:

foo = np.array([[0.0, 10.0], [0.13216, 12.11837], [0.25379, 42.05027], [0.30874, 13.11784]])

产生:

[[  0.       10.     ] [  0.13216  12.11837] [  0.25379  42.05027] [  0.30874  13.11784]]

如何标准化此数组的Y分量。所以它给了我类似的东西:

[[  0.       0.   ] [  0.13216  0.06 ] [  0.25379  1    ] [  0.30874  0.097]]

答案1

小编典典

参考此交叉验证链接,如何将数据标准化到0-1范围?,看来您可以在的最后一列执行最小-最大规格化foo

v = foo[:, 1]   # foo[:, -1] for the last columnfoo[:, 1] = (v - v.min()) / (v.max() - v.min())fooarray([[ 0.        ,  0.        ],       [ 0.13216   ,  0.06609523],       [ 0.25379   ,  1.        ],       [ 0.30874   ,  0.09727968]])

执行规范化的另一种方法(由OP建议)是使用sklearn.preprocessing.normalize,其产生的结果略有不同-

from sklearn.preprocessing import normalizefoo[:, [-1]] = normalize(foo[:, -1, None], norm=''max'', axis=0)fooarray([[ 0.        ,  0.2378106 ],       [ 0.13216   ,  0.28818769],       [ 0.25379   ,  1.        ],       [ 0.30874   ,  0.31195614]])

python numpy数组的numpy数组

python numpy数组的numpy数组

我在创建numpy数组的numpy数组时遇到问题。我将在一个循环中创建它:

a=np.array([])while(...):   ...   b= //a numpy array generated   a=np.append(a,b)   ...

所需结果:

[[1,5,3], [9,10,1], ..., [4,8,6]]

实际结果:

[1,5,3,9,10,1,... 4,8,6]

可能吗?我不知道数组的最终尺寸,因此无法使用固定尺寸对其进行初始化。

答案1

小编典典

永远不要numpy在循环中追加数组:与基本的Python相比,这是NumPy非常不擅长的一项操作。这是因为您要对每个数据进行完整复制append,这将花费您二次时间。

相反,只需将您的数组附加到Python列表中,并在最后进行转换即可;结果更简单,更快捷:

a = []while ...:    b = ... # NumPy array    a.append(b)a = np.asarray(a)

至于为什么您的代码不起作用:np.append根本不表现list.append出来。特别是,追加时不会创建新尺寸。您将必须创建具有二维的初始数组,然后附加一个显式的轴参数。

python – 花式索引沿多个轴的numpy数组的最佳实践

python – 花式索引沿多个轴的numpy数组的最佳实践

我正在尝试优化算法以减少内存使用量,并且我已经将此特定操作确定为一个痛点.

我有一个对称矩阵,沿着行的索引数组,以及沿着列的另一个索引数组(这只是我没有在行索引中选择的所有值).我觉得我应该能够同时传入两个索引,但我发现自己被迫沿着一个轴选择然后另一个轴,这导致一些内存问题,因为我实际上并不需要副本返回的数组,只是我正在计算的统计数据.这是我想要做的:

from scipy.spatial.distance import pdist,squareform
from sklearn import datasets
import numpy as np

iris = datasets.load_iris().data

dx = pdist(iris)
mat = squareform(dx)

outliers = [41,62,106,108,109,134,135]
inliers = np.setdiff1d( range(iris.shape[0]),outliers)

# What I want to be able to do:
scores = mat[inliers,outliers].min(axis=0)

以下是我实际做的工作:

# What I'm being forced to do:
s1 = mat[:,outliers]
scores = s1[inliers,:].min(axis=0)

因为我喜欢索引,所以s1是一个新数组而不是视图.我只需要这个数组用于一个操作,所以如果我可以消除在这里返回一个副本或至少使新数组变小(即通过尊重第二个花哨的索引选择,而我正在做第一个而不是两个独立的花式索引操作)这将是更可取的.

解决方法

“广播”适用于索引.您可以将内点转换为列矩阵(例如inliers.reshape(-1,1)或inliers [:,np.newaxis],因此它具有形状(m,1))和索引mat与第一列中的内容:

s1 = mat[inliers.reshape(-1,1),outliers]
scores = s1.min(axis=0)

我们今天的关于在磁盘上保留numpy数组的最佳方法磁盘的保留空间的分享已经告一段落,感谢您的关注,如果您想了解更多关于numpy学习笔记 - numpy数组的常见用法、NumPy数组的最小-最大归一化、python numpy数组的numpy数组、python – 花式索引沿多个轴的numpy数组的最佳实践的相关信息,请在本站查询。

本文标签: