假设我想有大小的numpy的阵列(n,m),其中n是非常大的,但有很多重复,即.0:n1是相同的,n1:n2是相同的等(有n2%n1!=0,但不是规则的间隔).有没有办法只为每个重复项存储一组值,同时拥有整个数组的视图?
例:
unique_values = np.array([[1,1,1], [2,2,2] ,[3,3,3]]) #these are the values i want to store in memory
index_mapping = np.array([0,0,1,1,1,2,2]) # a mapping between index of array above, with array below
unique_values_view = np.array([[1,1,1],[1,1,1],[2,2,2],[2,2,2],[2,2,2], [3,3,3],[3,3,3]]) #this is how I want the view to look like for broadcasting reasons
Run Code Online (Sandbox Code Playgroud)
我计划将数组(视图)乘以其他一些大小的数组(1,m),并取这个产品的点积:
other_array1 = np.arange(unique_values.shape[1]).reshape(1,-1) # (1,m)
other_array2 = 2*np.ones((unique_values.shape[1],1)) # (m,1)
output = np.dot(unique_values_view * other_array1, other_array2).squeeze()
Run Code Online (Sandbox Code Playgroud)
输出是长度为1D的数组n.
我有以下代码.它永远在Python中.必须有办法将此计算转换为广播......
def euclidean_square(a,b):
squares = np.zeros((a.shape[0],b.shape[0]))
for i in range(squares.shape[0]):
for j in range(squares.shape[1]):
diff = a[i,:] - b[j,:]
sqr = diff**2.0
squares[i,j] = np.sum(sqr)
return squares
Run Code Online (Sandbox Code Playgroud) 我需要创建一个2D数组,其中每一行可以以不同的数字开头和结尾.假设每行的第一个和最后一个元素被给出,所有其他元素只是根据行的长度进行插值在一个简单的例子中,假设我想创建一个3X3数组,其相同的开始位于0但不同的结尾由W给出:
array([[ 0., 1., 2.],
[ 0., 2., 4.],
[ 0., 3., 6.]])
Run Code Online (Sandbox Code Playgroud)
有没有比以下更好的方法:
D=np.ones((3,3))*np.arange(0,3)
D=D/D[:,-1]
W=np.array([2,4,6]) # last element of each row assumed given
Res= (D.T*W).T
Run Code Online (Sandbox Code Playgroud) python numpy vectorization multidimensional-array numpy-broadcasting
我有一个带有形状的numpy数组(34799, 32, 32, 3),意思是(num examples, width, height, channels).
现在我使用以下代码规范化图像数据:
def normalize(x):
return (x - 128) / 128
X_train_norm = normalize(X_train)
Run Code Online (Sandbox Code Playgroud)
但结果似乎不对,价值X_train[0][0][0]是[28 25 24],但输出X_train_norm[0][0][0]是[1.21875 1.1953125 1.1875].
我使用以下测试代码:
test = np.array([[[[28, 25, 24]]]])
print ((test - 128) / 128)
Run Code Online (Sandbox Code Playgroud)
输出:
[[[[-0.78125 -0.8046875 -0.8125 ]]]]
Run Code Online (Sandbox Code Playgroud)
为什么normalize函数得到错误的结果?
在python(使用numpy)中,我可以将数组广播为不同的形状:
>>> import numpy as np
>>> a = np.array([2,3,4])
>>> b = np.zeros((3,2))
>>> b[:,:] = np.zeros((3,2))
>>> b[:,:] = a[:,np.newaxis] #<-- np.newaxis allows `a` to be "broadcasted" to the same shape as b.
>>> b
array([[ 2., 2.],
[ 3., 3.],
[ 4., 4.]])
>>> c = np.zeros((2,3))
>>> c[:,:] = a[np.newaxis,:]
>>> c
array([[ 2., 3., 4.],
[ 2., 3., 4.]])
Run Code Online (Sandbox Code Playgroud)
有没有办法在fortran中达到同样的效果?我有一个子程序,希望2D传入一个数组 - 我想将我的1-D阵列"广播"到2-D,如上所述.由于它似乎很重要,我的2D数组确实有一个明确的界面.
作为旁注,我认为这个功能可能由reshape内在提供, - 像: …
我正在尝试使用欧几里德距离,基于它们与样本数据集的相似性,实现一种在测试数据集中聚类点的方法.测试数据集有500个点,每个点是N维向量(N = 1024).训练数据集大约有10000个点,每个点也是1024维度的向量.目标是找到每个测试点和所有采样点之间的L2距离,以找到最接近的样本(不使用任何python距离函数).由于测试阵列和训练阵列有不同的大小,我尝试使用广播:
import numpy as np
dist = np.sqrt(np.sum( (test[:,np.newaxis] - train)**2, axis=2))
Run Code Online (Sandbox Code Playgroud)
其中test是一个形状数组(500,1024),train是一个形状数组(10000,1024).我得到一个MemoryError.但是,相同的代码适用于较小的数组.例如:
test= np.array([[1,2],[3,4]])
train=np.array([[1,0],[0,1],[1,1]])
Run Code Online (Sandbox Code Playgroud)
是否有一种更有效的内存方式来进行上述计算而没有循环?基于在线帖子,我们可以使用矩阵乘法sqrt(X*X-2*X*Y + Y*Y)来实现L2范数.所以我尝试了以下方法:
x2 = np.dot(test, test.T)
y2 = np.dot(train,train.T)
xy = 2* np.dot(test,train.T)
dist = np.sqrt(x2 - xy + y2)
Run Code Online (Sandbox Code Playgroud)
由于矩阵具有不同的形状,当我尝试广播时,存在尺寸不匹配,我不确定什么是正确的广播方式(没有太多的Python广播经验).我想知道在Python中实现L2距离计算作为矩阵乘法的正确方法是什么,其中矩阵具有不同的形状.合成距离矩阵应该具有dist [i,j] =测试点i和样本点j之间的欧几里德距离.
谢谢
通过考虑以下方法可以解决这个问题,其他一些人和我实际上是错的:
说有一个
test = [ [ [0], 1 ],
[ [1], 1 ]
]
import numpy as np
nptest = np.array(test)
Run Code Online (Sandbox Code Playgroud)
背后的原因是什么?
>>> nptest[:,0]==[1]
array([False, False], dtype=bool)
Run Code Online (Sandbox Code Playgroud)
而有人
>>> nptest[0,0]==[1],nptest[1,0]==[1]
(False, True)
Run Code Online (Sandbox Code Playgroud)
>>> nptest==[1]
array([[False, True],
[False, True]], dtype=bool)
Run Code Online (Sandbox Code Playgroud)
要么
>>> nptest==1
array([[False, True],
[False, True]], dtype=bool)
Run Code Online (Sandbox Code Playgroud)
这是因为尺寸方面的退化导致了这种情况.
只是偶然发现了以下情况:
Python 3.6.0 (default, Jan 9 2017, 22:01:27)
[GCC 4.8.5] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>>
>>> np.version.version
'1.14.2'
>>>
>>> a = np.ones((100,), np.uint8)
>>> (a[:, None] == a).shape
(100, 100)
>>> a = np.ones((10000,), np.uint8)
>>> (a[:, None] == a).shape
(10000, 10000)
Run Code Online (Sandbox Code Playgroud)
到目前为止如此预期,但现在:
>>> a = np.ones((1000000,), np.uint8)
>>> (a[:, None] == a).shape
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'bool' object …Run Code Online (Sandbox Code Playgroud) 我有一个形状(4,3)的数据帧如下:
In [1]: import pandas as pd
In [2]: import numpy as np
In [3]: x = pd.DataFrame(np.random.randn(4, 3), index=np.arange(4))
In [4]: x
Out[4]:
0 1 2
0 0.959322 0.099360 1.116337
1 -0.211405 -2.563658 -0.561851
2 0.616312 -1.643927 -0.483673
3 0.235971 0.023823 1.146727
Run Code Online (Sandbox Code Playgroud)
我想将数据帧的每一列与numpy数组形状(4,)相乘:
In [9]: y = np.random.randn(4)
In [10]: y
Out[10]: array([-0.34125522, 1.21567883, -0.12909408, 0.64727577])
Run Code Online (Sandbox Code Playgroud)
在numpy中,以下广播技巧有效:
In [12]: x.values * y[:, None]
Out[12]:
array([[-0.32737369, -0.03390716, -0.38095588],
[-0.25700028, -3.11658448, -0.68303043],
[-0.07956223, 0.21222123, 0.06243928],
[ 0.15273815, 0.01541983, 0.74224861]])
Run Code Online (Sandbox Code Playgroud)
但是,它在pandas dataframe的情况下不起作用,我得到以下错误: …
术语广播描述了numpy如何在算术运算期间处理具有不同形状的数组.
Example 1:
from numpy import array
a = array([1.0,2.0,3.0])
b = array([2.0,2.0,2.0]) # multiply element-by-element ()
a * b
>> array([ 2., 4., 6.])
Example 2 :
from numpy import array
a = array([1.0,2.0,3.0])
b = 2.0 # broadcast b to all a
a * b
>>array([ 2., 4., 6.])
Run Code Online (Sandbox Code Playgroud)
我们可以将在算术运算期间被拉伸的标量b想象成具有与a相同形状的数组.Numpy足够聪明,可以使用原始标量值,而无需实际制作副本,以便广播操作尽可能具有内存和计算效率(b是标量,而不是数组)
@Eric Duminil在另一个内存性能问题中做出的一个小基准测试表明,广播在速度和内存方面存在差异
但是,我引用上面链接的同一篇文章:
有些情况下,广播是一个坏主意,因为它会导致内存的低效使用,从而减慢计算速度
问题是:当广播使用不必要的大量内存并导致性能低下时?换句话说,当我们应该使用混合广播/python循环算法而不是纯粹的广播approch?