我已经尝试初始化csc_matrix并csr_matrix从(data, (rows, cols))文档建议的值列表中进行初始化.
sparse = csc_matrix((data, (rows, cols)), shape=(n, n))
Run Code Online (Sandbox Code Playgroud)
问题是,我实际上有用于产生方法data,rows和cols载体引入重复对一些点.默认情况下,scipy会添加重复条目的值.但是,在我的情况下,这些重复项data对于给定的值具有完全相同的值(row, col).
我想要实现的是让scipy忽略第二个条目,如果已经存在,而不是添加它们.
忽略我可以改进生成算法以避免生成重复的事实,是否有参数或其他方法来创建忽略重复的稀疏矩阵?
目前两个条目与data = [4, 4]; cols = [1, 1]; rows = [1, 1];生成的稀疏矩阵,其值在(1,1)是8同时所希望的值是4.
>>> c = csc_matrix(([4, 4], ([1,1],[1,1])), shape=(3,3))
>>> c.todense()
matrix([[0, 0, 0],
[0, 8, 0],
[0, 0, 0]])
Run Code Online (Sandbox Code Playgroud)
我也知道我可以通过使用二维numpy unique函数来过滤它们,但是列表非常大,所以这不是一个真正有效的选项.
问题的其他可能答案:有没有办法指定如何处理重复项?即保持min或max代替默认sum?
我想在3D阵列的给定方向上获得2D切片,其中direction(或者将要从中提取切片的轴)由另一个变量给出.
假设idx3D阵列中的2D切片的索引以及direction获得该2D切片的轴,初始方法将是:
if direction == 0:
return A[idx, :, :]
elif direction == 1:
return A[:, idx, :]
else:
return A[:, :, idx]
Run Code Online (Sandbox Code Playgroud)
我很确定必须有一种方法可以在不进行条件限制的情况下执行此操作,或者至少不是在原始python中.numpy有这个捷径吗?
到目前为止我发现的更好的解决方案(动态地做),依赖于转置运算符:
# for 3 dimensions [0,1,2] and direction == 1 --> [1, 0, 2]
tr = [direction] + range(A.ndim)
del tr[direction+1]
return np.transpose(A, tr)[idx]
Run Code Online (Sandbox Code Playgroud)
但我想知道是否有更好/更容易/更快的功能,因为对于3D,转置代码几乎看起来比3 if/elif更糟糕.它对ND的推广更为普遍,N越大,代码相比就越漂亮,但对于3D来说却是完全相同的.
scipy(或其他类似的库)中是否有办法仅在某些所需的点上获取具有给定内核的图像的卷积?
我正在寻找类似的东西:
ndimage.convolve(image, kernel, mask=mask)
Run Code Online (Sandbox Code Playgroud)
其中mask包含True(或1)每当内核需要被应用,False(或0)其他方式。
编辑:示例python代码可以完成我想做的事情(但不比使用scipy进行整个图像卷积要快):
def kernel_responses(im, kernel, mask=None, flatten=True):
if mask is None:
mask = np.ones(im.shape[:2], dtype=np.bool)
ks = kernel.shape[0]//2
data = np.pad(im, ks, mode='reflect')
y, x = np.where(mask)
responses = np.empty(y.shape[0], float)
for k, (i, j) in enumerate(zip(y, x)):
responses[k] = (data[i:i+ks*2+1, j:j+ks*2+1] * kernel).sum()
if flatten:
return responses
result = np.zeros(im.shape[:2], dtype=float)
result[y, x] = responses
return result
Run Code Online (Sandbox Code Playgroud)
上面的代码使用wrap边界条件来完成这项工作,但是内部循环在python中进行,因此很慢。我在想,如果有东西在快已经实施scipy/ opencv/ …
这是一个非常愚蠢的问题,但我正在运行一些任务并通过以下方式捕获错误:
try:
run_something()
except Exception as e:
handle_error(str(e))
Run Code Online (Sandbox Code Playgroud)
我想将错误消息作为String,因为我正在使用UI,我想在窗口中显示错误.
问题可以复制为:
>>> import numpy as np
>>> np.range(1e10)
MemoryError Traceback (most recent call last)
<ipython-input-4-20a59c2069b2> in <module>()
----> 1 np.arange(1e10)
MemoryError:
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试捕获错误并打印其消息(我希望它是类似"MemoryError"的东西:
try:
np.arange(1e10)
except Exception as e:
print(str(e))
print("Catched!")
Run Code Online (Sandbox Code Playgroud)
我得到的唯一输出是"Catched!".这是如此愚蠢,我正在做UI和线程的一些工作,并花了我一段时间才意识到问题是一个内存错误,根本没有消息.
MemoryError是唯一被转换为空字符串的异常吗?因为如果是这种情况我可以检查它.如果没有,如何将其消息作为字符串?
我有一个具有唯一正整数的数组/集,即
>>> unique = np.unique(np.random.choice(100, 4, replace=False))
Run Code Online (Sandbox Code Playgroud)
并且包含从前一个数组中采样的多个元素的数组,例如
>>> A = np.random.choice(unique, 100)
Run Code Online (Sandbox Code Playgroud)
我想将数组的值映射A到这些值出现的位置unique.
到目前为止,我找到的最佳解决方案是通过映射数组:
>>> table = np.zeros(unique.max()+1, unique.dtype)
>>> table[unique] = np.arange(unique.size)
Run Code Online (Sandbox Code Playgroud)
上面为每个元素分配了数组上的索引,因此可以在以后用于映射A高级索引:
>>> table[A]
array([2, 2, 3, 3, 3, 3, 1, 1, 1, 0, 2, 0, 1, 0, 2, 1, 0, 0, 2, 3, 0, 0, 0,
0, 3, 3, 2, 1, 0, 0, 0, 2, 1, 0, 3, 0, 1, 3, 0, 1, 2, 3, 3, 3, 3, 1,
3, …Run Code Online (Sandbox Code Playgroud) 我有一个很大的可迭代,实际上是一个大的迭代,由下式给出:
itertools.permutations(range(10))
Run Code Online (Sandbox Code Playgroud)
我想访问第一百万个元素.我已经以某种不同的方式解决了问题.
将iterable转换为list并获取1000000th元素:
return list(permutations(range(10)))[999999]
Run Code Online (Sandbox Code Playgroud)手动滑动元素直到999999:
p = permutations(range(10))
for i in xrange(999999): p.next()
return p.next()
Run Code Online (Sandbox Code Playgroud)手动滑动元素v2:
p = permutations(range(10))
for i, element in enumerate(p):
if i == 999999:
return element
Run Code Online (Sandbox Code Playgroud)使用itertools中的islice:
return islice(permutations(range(10)), 999999, 1000000).next()
Run Code Online (Sandbox Code Playgroud)但我仍然觉得这些都不是python的优雅方式.第一个选项太昂贵,它需要计算整个迭代只是为了访问单个元素.如果我没有错,那么islice在内部执行的方法与我在方法2中所做的相同,并且几乎完全是第3次,也许它有更多的冗余操作.
所以,我只是好奇,想知道是否有python以其他方式访问迭代的具体元素,或者至少以更优雅的方式跳过第一个元素,或者如果我只需要使用一个以上.
我知道我可以执行以下操作:
import numpy as np
c = np.random.randn(20, 2)
a = c[:, 0]
b = c[:, 1]
Run Code Online (Sandbox Code Playgroud)
这里,a和分别是指向 的第一列和第二列的b指针。c修改a或b将要改变c(相互相同)。
然而,我想要达到的目标却恰恰相反。我想创建一个 2D 内存视图,其中每列(或行)将指向不同的 1D 数组的内存。假设我已经有两个一维数组,是否可以为这些数组创建一个二维视图,其中每行/列都指向它们中的每一个?
我可以c通过以下方式a创建:b
c = np.c_[a, b]
Run Code Online (Sandbox Code Playgroud)
然而,这会将a和b内存复制到c. 我可以通过修改反映在相应数组或一维数组中的元素来以某种方式创建 的c“视图”吗?[a b]cab
假设我们有一个带NxMxD形状的数组。我想得到一个带有D NxM数组的列表。
正确的做法是:
np.dsplit(myarray, D)
Run Code Online (Sandbox Code Playgroud)
但是,这将返回D NxMx1数组。
我可以通过执行以下操作来达到预期的结果:
[myarray[..., i] for i in range(D)]
Run Code Online (Sandbox Code Playgroud)
或者:
[np.squeeze(subarray) for subarray in np.dsplit(myarray, D)]
Run Code Online (Sandbox Code Playgroud)
但是,我觉得需要执行额外的操作有点多余。我是否缺少任何numpy返回所需结果的函数?
考虑一个二维数组:
arr = np.zeros((10,10))
arr[3:7,3:7] = 1
Run Code Online (Sandbox Code Playgroud)
现在我想使用掩码将其中的一部分替换为其他值:
mask = np.ones((5,5)).astype(bool)
arr[5:,5:][mask] = 2
Run Code Online (Sandbox Code Playgroud)
是否可以保留原始文件中的非零元素arr并使用掩码仅替换零元素?我想避免通过平面索引来这样做,因为我处理的数组是大型 3D 数组(大约 1000x1000x1000)。
编辑:一些附加信息:
我想避免更改掩码,这包括在数组非零的情况下将其设置为 False 以及调整其大小。原因是该操作需要重复多次,并将掩模放置在阵列的不同区域。由于数组非常大,因此最好避免复制数据。
np.set_printoptions允许自定义numpy 数组的漂亮打印。然而,对于不同的用例,我希望有不同的打印选项。
理想情况下,无需每次都重新定义整个选项即可完成此操作。我正在考虑使用本地范围,例如:
with np.set_printoptions(precision=3):
print my_numpy_array
Run Code Online (Sandbox Code Playgroud)
但是,set_printoptions似乎不支持with语句,因为会抛出错误(AttributeError: __exit__)。有没有什么方法可以在不创建自己的漂亮打印类的情况下完成这项工作?我知道我可以创建自己的上下文管理器:
class PrettyPrint():
def __init__(self, **options):
self.options = options
def __enter__(self):
self.back = np.get_printoptions()
np.set_printoptions(**self.options)
def __exit__(self, *args):
np.set_printoptions(**self.back)
Run Code Online (Sandbox Code Playgroud)
并将其用作:
>>> print A
[ 0.29276529 -0.01866612 0.89768998]
>>> with PrettyPrint(precision=3):
print A
[ 0.293 -0.019 0.898]
Run Code Online (Sandbox Code Playgroud)
然而,有没有比创建新类更直接的东西(最好已经内置)?
这可能是一个愚蠢的问题,但我无法找到正确的答案。我想将(2000, 2000, 2000)零数组的二进制表示(不要问为什么)存储到磁盘中,二进制格式。实现这一目标的传统方法是:
with open('myfile', 'wb') as f:
f.write('\0' * 4 * 2000 * 2000 * 2000) # 4 bytes = float32
Run Code Online (Sandbox Code Playgroud)
但这意味着创建一个非常大的字符串,这根本不是必需的。我知道另外两个选项:
迭代元素并一次存储一个字节(非常慢)
创建一个 numpy 数组并将其刷新到磁盘(与上面示例中的字符串创建一样消耗内存)
我正在寻找类似的东西write(char, ntimes)(因为它存在于 C 和其他语言中)以char ntimesC 速度而不是 Python 循环速度复制到磁盘上,而不必在内存上创建如此大的数组。
像SLIC这样的图像分割算法有什么意义?大多数对象检测算法无论如何都适用于整个(方形)子图像集.
分割图像的唯一可想到的好处是,现在,分类器具有可用的形状信息.是对的吗?
我所知道的大多数分类器都采用矩形输入图像.哪些分类器允许您将可变大小的图像片段传递给它们?
image-processing object-detection computer-vision image-segmentation
python ×9
numpy ×8
arrays ×2
indexing ×2
scipy ×2
binary ×1
convolution ×1
duplicates ×1
exception ×1
file ×1
iterable ×1
iterator ×1
pretty-print ×1
scikit-image ×1
split ×1