你可以从两个 np.float 一维数组创建一个 np.complex128 一维数组而不复制吗?
Posted
技术标签:
【中文标题】你可以从两个 np.float 一维数组创建一个 np.complex128 一维数组而不复制吗?【英文标题】:can you create a np.complex128 1d array from two np.float 1d arrays without copy? 【发布时间】:2020-03-12 22:35:22 【问题描述】:设置:
我有两个来自共享内存 reals
和 imags
的数组:
#/usr/bin/env python2
reals = multiprocessing.RawArray('d', 10000000)
imags = multiprocessing.RawArray('d', 10000000)
然后我将它们设为numpy
-arrays,命名为reals2
和imags2
,没有任何副本:
import numpy as np
reals2 = np.frombuffer(reals)
imags2 = np.frombuffer(imags)
# check if the objects did a copy
assert reals2.flags['OWNDATA'] is False
assert imags2.flags['OWNDATA'] is False
然后我想创建一个np.complex128
1D-array data
,再次不复制数据,但我不知道该怎么做。
问题:
你能从一对浮点数组中创建一个np.complex128
一维数组data
,而不需要复制,是/否?
如果是,怎么做?
【问题讨论】:
数组的数据缓冲区,无论 dtype 是什么,都是一个连续的块。 【参考方案1】:简短的回答:没有。但是如果你控制了发件人,那么有一个不需要复制的解决方案。
更长的答案:
根据我的研究,我认为没有办法在不复制数据的情况下从两个单独的数组创建numpy
复杂数组
IMO 我认为你不能这样做,因为所有 numpy
编译的 c 代码都假定交错的真实图像数据
如果您控制发送者,您无需任何复制操作即可获取您的数据。方法如下!
#!/usr/bin/env python2
import multiprocessing
import numpy as np
# parent process creates some data that needs to be shared with the child processes
data = np.random.randn(10) + 1.0j * np.random.randn(10)
assert data.dtype == np.complex128
# copy the data from the parent process to shared memory
shared_data = multiprocessing.RawArray('d', 2 * data.size)
shared_data[0::2] = data.real
shared_data[1::2] = data.imag
# simulate the child process getting only the shared_data
data2 = np.frombuffer(shared_data)
assert data2.flags['OWNDATA'] is False
assert data2.dtype == np.float64
assert data2.size == 2 * data.size
# convert reals to complex
data3 = data2.view(np.complex128)
assert data3.flags['OWNDATA'] is False
assert data3.dtype == np.complex128
assert data3.size == data.size
assert np.all(data3 == data)
# done - if no AssertionError then success
print 'success'
提示:https://***.com/a/32877245/52074 作为一个很好的起点。
这里是如何执行相同的处理,但启动多个进程并从每个进程取回数据并验证返回的数据
#!/usr/bin/env python2
import multiprocessing
import os
# third-party
import numpy as np
# constants
# =========
N_POINTS = 3
N_THREADS = 4
# functions
# =========
def func(index, shared_data, results_dict):
# simulate the child process getting only the shared_data
data2 = np.frombuffer(shared_data)
assert data2.flags['OWNDATA'] is False
assert data2.dtype == np.float64
# convert reals to complex
data3 = data2.view(np.complex128)
assert data3.flags['OWNDATA'] is False
assert data3.dtype == np.complex128
print '[child.pid=%s,type=%s]: %s'%(os.getpid(), type(shared_data), data3)
# return the results in a SLOW but relatively easy way
results_dict[os.getpid()] = np.copy(data3) * index
# the script
# ==========
if __name__ == '__main__':
# parent process creates some data that needs to be shared with the child processes
data = np.random.randn(N_POINTS) + 1.0j * np.random.randn(N_POINTS)
assert data.dtype == np.complex128
# copy the data from the parent process to shared memory
shared_data = multiprocessing.RawArray('d', 2 * data.size)
shared_data[0::2] = data.real
shared_data[1::2] = data.imag
print '[parent]: ', type(shared_data), data
# do multiprocessing
manager = multiprocessing.Manager()
results_dict = manager.dict()
processes = []
for index in xrange(N_THREADS):
process = multiprocessing.Process(target=func, args=(index, shared_data, results_dict))
processes.append(process)
for process in processes:
process.start()
for process in processes:
process.join()
# get the results back from the processes
results = [results_dict[process.pid] for process in processes]
# verify the values from the processes
for index in xrange(N_THREADS):
result = results[index]
assert np.all(result == data * index)
del processes
# done
print 'success'
【讨论】:
以上是关于你可以从两个 np.float 一维数组创建一个 np.complex128 一维数组而不复制吗?的主要内容,如果未能解决你的问题,请参考以下文章
《LeetCode之每日一题》:253.将一维数组转变成二维数组
Leetcode刷题100天—2022. 将一维数组转变成二维数组(数组)—day55