myx=np.array([2.4,0.2,0.5,1.6])
myy=np.array([10.1,3.2,7.5,8.6,1,0.1,11,18])
我想编写一个程序,使用贪心算法将“myx”的每个元素与“myy”匹配。匹配将是1:1,卡尺距离<= 0.5,无需更换。 算法很简单:
import numpy as np
myx=np.array([2.4,0.2,0.5,1.6])
myy=np.array([10.1,3.2,7.5,8.6,1,0.1,11,1.4])
Xxx=np.transpose(np.repeat(myx[:, np.newaxis], myy.size , axis=1))
Yyy=np.repeat(myy[:, np.newaxis], myx.size , axis=1)
# define a caliper
calp=0.5
matches = {}
dist = np.abs(Xxx-Yyy)
print('Before loop distance matrix',dist)
for m in range(0, myx.size):
if (np.nanmin(dist[:,m]) <= calp) or not calp:
matches[m] = np.nanargmin(dist[:,m])
dist[matches[m],:]=None
print('Match Pairs:',matches)
print('After loop distance matrix',dist)
问题是我不想在“np”或“panda”中使用任何东西,但只想使用Tensorflow框架。我已经写了部分程序,但发现它比我最初的想法更难。有人能帮我吗?顺便说一句,这是我第一次尝试使用tensorflow ..
import math
import numpy as np
import tensorflow as tf
#myx = np.random.uniform(low=0.5, high=3.5, size=(5000,))
#myy=np.random.uniform(low=0.8, high=5.0, size=(50000,))
myx=np.array([2.4,0.2,0.5,1.6])
myy=np.array([10.1,3.2,7.5,8.6,1,0.1,11,18])
Xxx=np.transpose(np.repeat(myx[:, np.newaxis], myy.size , axis=1))
Yyy=np.repeat(myy[:, np.newaxis], myx.size , axis=1)
X = tf.placeholder(tf.float64, shape=(myy.size,myx.size))
Y = tf.placeholder(tf.float64, shape=(myy.size,myx.size))
# define a caliper
calp=tf.constant(0.5,tf.float64)
with tf.device('/cpu:0'):
dist = tf.abs(tf.subtract(X,Y))
# Use an explicit shape for `i`.
i = tf.placeholder(dtype='int64', shape=[])
# Add a second unused argument to `condition()`.
def condition(i, *arg):
return i <= myx.size-1
# Add a second unused argument to `b()`.
def b(i, temp, _):
tfslic = dist[0:myy.size, i]
# Drop the `axis` argument from `tf.reduce_min()`
minVal=tf.reduce_min(tfslic)
y = tf.cond(
tf.less_equal(minVal, calp),
# Reshape the output of `tf.argmin()` to be a scalar.
lambda: tf.argmin(tfslic, 0),
# Explicitly convert the false-branch value to `tf.int64`.
lambda: tf.constant(99999, dtype=tf.int64))
'''
:::::::::::::PROBLEM START HERE:::::::::::
For each tf.while_loop, with index "i"
if the minimum value of distance matrix dist[,i] <= caliper
then output the first min value index occurs i.e. (y,i)
Then set dist[y,]=[None, None, None, None]
Given the example matix "myx","myy";
The while loop should output match pair indx [[0,None],[1,5],[2,4],[3,None]]
'''
varDist=tf.Variable(dist)
temp = tf.cond(
tf.less_equal(minVal, calp),
# Set dist matrix row y to [None, None, None, None].
lambda: tf.assign(varDist[y,],[9999.,9999.,9999.,9999.]),
# Do nothing.
lambda: tf.Variable(dist))
return i+1, y, temp
# Add a dummy initial value for the second loop variable.
# Rename the first return value to `i_out` to avoid clashing with `i` above.
i_out, r, dist= tf.while_loop(condition, b, [i, dist, tf.constant(0, dtype=tf.int64)])
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
dmat = sess.run(dist, feed_dict={X:Xxx, Y: Yyy,i:0})
sess.close()
print(dmat)
答案 0 :(得分:0)
让我重新提出问题,看看我是否正确理解。问题是,对于x
中的每个元素myx
,找到myy
中与x
最接近的元素,如果距离小于a myx
则匹配它们卡尺。
匹配结果也可以表示为一个列表(长度与myy
相同),如果最小,则此列表中的每个元素都是-1
或npstyle()
中的索引距离大于卡尺。
如果您同意上述重构,那么有一种解决问题的方法,如函数tf_style()
中所示,可以很容易地转换为import numpy as np
import tensorflow as tf
def npstyle_0():
myx=np.array([2.4,0.2,0.5,1.6])
myy=np.array([10.1,3.2,7.5,8.6,1,0.1,11,1.4])
Xxx = np.transpose(np.repeat(myx[:, np.newaxis], myy.size, axis=1))
Yyy = np.repeat(myy[:, np.newaxis], myx.size, axis=1)
# define a caliper
calp = 0.5
matches = {}
dist = np.abs(Xxx - Yyy)
print('Before loop distance matrix', dist)
for m in range(0, myx.size):
if (np.nanmin(dist[:, m]) <= calp) or not calp:
matches[m] = np.nanargmin(dist[:, m])
dist[matches[m], :] = None
print('Match Pairs:', matches)
print('After loop distance matrix', dist)
def npstyle():
myx=np.array([2.4,0.2,0.5,1.6])
myy=np.array([10.1,3.2,7.5,8.6,1,0.1,11,1.4])
# myx=np.array([3.0, 0.2, 4.0])
# myy=np.array([10.1, 3.2, 0.1, 7.5])
Xxx=np.transpose(np.repeat(myx[:, np.newaxis], myy.size, axis=1))
Yyy=np.repeat(myy[:, np.newaxis], myx.size , axis=1)
# define a caliper
calp=0.5
dist = np.abs(Xxx-Yyy)
argmin = np.nanargmin(dist, 0)
print('Before loop distance matrix', dist)
match_dist = dist[argmin, np.arange(myx.size)]
match_bool = match_dist <= calp
matches = np.where(match_bool, np.nanargmin(dist, 0), -1)
print matches
print 'end np style.'
def tf_style():
X = tf.placeholder(tf.float64, shape=(None,)) # setting (None,) allows to give an array of any length.
Y = tf.placeholder(tf.float64, shape=(None,))
shape_x, shape_y = tf.shape(X)[0], tf.shape(Y)[0]
Xxx = tf.reshape(tf.tile(X, [shape_y]), (shape_y, shape_x))
Yyy = tf.reshape(tf.tile(Y, [shape_x]), (shape_x, shape_y))
calp = 0.5
dist = tf.abs(Xxx - tf.transpose(Yyy))
argmin = tf.argmin(dist, axis=0, output_type=tf.int32)
match_dist = tf.diag_part(tf.gather(dist, argmin))
match_bool = tf.less_equal(match_dist, calp)
matches = tf.where(match_bool, argmin, tf.fill([shape_x], -1))
# ========= session of tensorflow ===========
# gpu config
# gpu_options = tf.GPUOptions(allow_growth=False)
# config = tf.ConfigProto(log_device_placement=False, gpu_options=gpu_options)
# sess = tf.Session(config)
sess = tf.Session()
feed_dict = {X: [2.4,0.2,0.5,1.6], Y: [10.1,3.2,7.5,8.6,1,0.1,11,1.4]}
[a, b, d, e] = sess.run([Xxx, Yyy, dist, matches],
feed_dict=feed_dict)
print a
print b
print d
print e
if __name__ == '__main__':
# npstyle_0()
npstyle()
tf_style()
。
{{1}}