我有两个数据帧,一个(10,2)和一个(4,2),我正在寻找一种更快/更pythonic的方式来逐行比较它们。
x = pd.DataFrame([range(10),range(2,12)])
x = x.transpose()
y = pd.DataFrame([[5,8],[2,3],[5,5]])
我想构建一个比较矩阵(10,3),它显示第一个数据帧中的哪些行符合第二个数据帧中的以下要求。 x 1值必须是> = y [0]值,x [0]值必须是< = y 1值。实际上,数据是日期,但为了简单起见,我刚刚使用整数来使这个例子更容易理解。我们在时间段内测试重叠,因此逻辑表明在各个表的周期中必定存在一些重叠。
arr = np.zeros((len(x),len(y)), dtype=bool)
for xrow in x.index:
for yrow in y.index:
if x.loc[xrow,1] >= y.loc[yrow,0] and x.loc[xrow,0] <= y.loc[yrow,1]:
arr[xrow,yrow] = True
arr
上面的蛮力方法太慢了。关于如何对此进行矢量化或进行某种转置矩阵比较的任何建议?
答案 0 :(得分:2)
您可以将x
,y
转换为NumPy数组,然后使用np.newaxis/None
扩展维度,这会在执行相同操作时引入NumPy's broadcasting
。因此,所有这些比较和输出布尔数组都将以矢量化方式创建。实现看起来像这样 -
X = np.asarray(x)
Y = np.asarray(y)
arr = (X[:,None,1] >= Y[:,0]) & (X[:,None,0] <= Y[:,1])
示例运行 -
In [207]: x = pd.DataFrame([range(10),range(2,12)])
...: x = x.transpose()
...: y = pd.DataFrame([[5,8],[2,3],[5,5]])
...:
In [208]: X = np.asarray(x)
...: Y = np.asarray(y)
...: arr = (X[:,None,1] >= Y[:,0]) & (X[:,None,0] <= Y[:,1])
...:
In [209]: arr
Out[209]:
array([[False, True, False],
[False, True, False],
[False, True, False],
[ True, True, True],
[ True, False, True],
[ True, False, True],
[ True, False, False],
[ True, False, False],
[ True, False, False],
[False, False, False]], dtype=bool)