在Python中匹配两个不同的数组并创建一个新数组

3

我有两个二维数组,需要创建一个新的数组,并通过第二个数组进行过滤,其中第一列索引匹配。这两个数组的大小不同。

基本上,想法如下:

file A

#x   y
1   2
3   4
2   2
5   4
6   4
7   4


file B

#x1    y1
0       1
1       1
11      1
5       1
7       1
My expected output 2D array should look like

#newx     newy
1         1
5         1
7         1

我尝试了以下方法:

我按照以下方式进行了尝试:

match =[]
for i in range(len(x)):
    if x[i] == x1[i]:
        new_array = x1[i]
        match.append(new_array)

print match

这似乎不起作用。请建议一种创建新的二维数组的方法。

6个回答

5
尝试使用 np.isin
arr1 = np.array([[1,3,2,5,6,7], [2,4,2,4,4,4]])
arr2 = np.array([[0,1,11,5,7], [1,1,1,1,1]])
arr2[:,np.isin(arr2[0], arr1[0])]
array([[1, 5, 7],
       [1, 1, 1]])

np.isin(arr2[0], arr1[0])检查arr2[0]的每个元素是否在arr1[0]中,然后我们使用这个结果作为布尔索引数组来选择arr2中的元素。


4

如果你将A的第一个元素作为一个集合,那么找到与B中相同元素就比较容易了:

代码:

a = ((1, 2), (3, 4), (2, 2), (5, 4), (6, 4), (7, 4))
b = ((0, 1), (1, 1), (11, 1), (5, 1), (7, 1))

in_a = {i[0] for i in a}
new_b = [i for i in b if i[0] in in_a]

print(new_b)

结果:

[(1, 1), (5, 1), (7, 1)]

将输出结果保存为文件:

with open('output.txt', 'w') as f:
    for value in new_b:
        f.write(' '.join(str(v) for v in value) + '\n')

请问您能否解释一下如何从我的大数组中创建成对的数据?就像您创建a和b数组的方式一样? - bhjghjh
@bhjghjh,如果我理解你的问题,我很乐意回答。也许你可以重新表达一下问题?如果你有另一个问题,请随时在这里留言,以确保我看到它。祝好运... - Stephen Rauch
非常感谢您的帮助。在我的原始问题中,我没有(x,y)作为一对出现。我只有两个不同的.txt文件,从中我正在读取两列作为数组。您能否修改您的代码,将结果输出为文件中的两列? - bhjghjh

2
#!/usr/bin/env python3

from io import StringIO
import pandas as pd

fileA = """x   y
1   2
3   4
2   2
5   4
6   4
7   4
"""

fileB = """x1    y1
0       1
1       1
11      1
5       1
7       1
"""


df1 = pd.read_csv(StringIO(fileA), delim_whitespace=True, index_col="x")
df2 = pd.read_csv(StringIO(fileB), delim_whitespace=True, index_col="x1")

df = pd.merge(df1, df2, left_index=True, right_index=True)
print(df["y1"])

# 1    1
# 5    1
# 7    1

https://pandas.pydata.org/pandas-docs/stable/merging.html#database-style-dataframe-joining-merging


2
如果您使用pandas:
import pandas as pd

A = pd.DataFrame({'x': pd.Series([1,3,2,5,6,7]), 'y': pd.Series([2,4,2,4,4,4])})
B = pd.DataFrame({'x1': pd.Series([0,1,11,5,7]), 'y1': 1})

C = A.join(B.set_index('x1'), on='x')

如果您想要删除不需要的行/列并重命名列:

C = A.join(B.set_index('x1'), on='x')
C = C.drop(['y'], axis=1)
C.columns = ['newx', 'newy']

这会给你:

>>> C
   newx  newy
0     1   1.0
3     5   1.0
5     7   1.0

如果您要使用数组、数据框等进行工作,那么pandas绝对值得一试:https://pandas.pydata.org/pandas-docs/stable/10min.html

1
假设您在2D数组中有(x, y)对,简单的循环可能有效:
arr1   = [[1, 2], [3, 4], [2, 2]]
arr2   = [[0, 1], [1, 1], [11, 1]]
result = []

for pair1 in arr1:
    for pair2 in arr2:
        if (pair1[0] == pair2[0]):
            result.append(pair2)

print(result)

1

对于较小的数组来说不是最佳解决方案,但对于非常大的数组,它可以快速工作 -

import numpy as np
import pandas as pd

n1 = np.transpose(np.array([[1,3,2,5,6,7], [2,4,2,4,4,4]]))
n2 = np.transpose(np.array([[0,1,11,5, 7], [1,1,1,1,1]]))
np.array(pd.DataFrame(n1).merge(pd.DataFrame(n2), on=0, how='inner').drop('1_x', axis=1))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接