การเปรียบเทียบอาร์เรย์ numpy สองรายการเพื่อให้สอดคล้องกับเงื่อนไขสองประการ
พิจารณาอาร์เรย์ numpy สองอาร์เรย์ที่มีรูปร่างเหมือนกันคือ A และ B ประกอบด้วย 1 และ 0 ตัวอย่างเล็ก ๆ แสดง:
A = [[1 0 0 1] B = [[0 0 0 0]
[0 0 1 0] [0 0 0 0]
[0 0 0 0] [1 1 0 0]
[0 0 0 0] [0 0 1 0]
[0 0 1 1]] [0 1 0 1]]
ตอนนี้ฉันต้องการกำหนดค่าให้กับตัวแปรบูลีนสองตัวtest1และtest2ดังนี้:
test1 : มีอย่างน้อยหนึ่งกรณีหรือไม่ที่ 1 ในA
คอลัมน์และ 1 ในB
คอลัมน์SAME มีความแตกต่างของแถวเท่ากับ 1 หรือ 2 ถ้าเป็นเช่นนั้นtest1 = True หรือ False
ในตัวอย่างด้านบนคอลัมน์ 0 ของอาร์เรย์ทั้งสองมี 1s ที่ห่างกัน 2 แถวดังนั้นtest1 = True (มีอินสแตนซ์อื่น ๆ ในคอลัมน์ 2 เช่นกัน แต่นั่นไม่สำคัญ - เราต้องการอินสแตนซ์เดียวเท่านั้น)
test2 : ค่า 1 ในA
และB
ทั้งหมดมีที่อยู่อาร์เรย์ที่แตกต่างกันหรือไม่ ถ้าเป็นเช่นนั้นtest2 = True มิฉะนั้น False
ในตัวอย่างด้านบนอาร์เรย์ทั้งสองมี[4,3] = 1
ดังนั้นtest2 = False
ฉันกำลังดิ้นรนเพื่อหาวิธีที่มีประสิทธิภาพในการดำเนินการนี้และขอขอบคุณสำหรับความช่วยเหลือ
คำตอบ
นี่คือวิธีง่ายๆในการทดสอบว่าอาร์เรย์สองอาร์เรย์มีรายการหนึ่งองค์ประกอบแยกจากกันในคอลัมน์เดียวกันหรือไม่ (ในทิศทางเดียวเท่านั้น):
(A[1:, :] * B[:-1, :]).any(axis=None)
ดังนั้นคุณสามารถทำได้
test1 = (A[1:, :] * B[:-1, :] + A[:-1, :] * B[1:, :]).any(axis=None) or (A[2:, :] * B[:-2, :] + A[:-2, :] * B[2:, :]).any(axis=None)
การทดสอบครั้งที่สองทำได้โดยการแปลงสถานที่เป็นดัชนีเรียงซ้อนกันและใช้np.unique
เพื่อนับจำนวนรายการที่ซ้ำกัน รายการที่ซ้ำกันสามารถมาจากดัชนีเดียวกันในสองอาร์เรย์เท่านั้นเนื่องจากอาร์เรย์จะไม่มีดัชนีซ้ำกัน เราสามารถเร่งความเร็วในการคำนวณเพิ่มเติมได้โดยใช้flatnonzero
แทนnonzero
:
test2 = np.all(np.unique(np.concatenate((np.flatnonzero(A), np.flatnonzero(B))), return_counts=True)[1] == 1)
การทดสอบที่มีประสิทธิภาพมากขึ้นจะใช้np.intersect1d
ในลักษณะเดียวกัน:
test2 = not np.intersect1d(np.flatnonzero(A), np.flatnonzero(B)).size
คุณสามารถใช้ masked_arrays และสำหรับงานที่สองคุณสามารถทำได้:
A_m = np.ma.masked_equal(A, 0)
B_m = np.ma.masked_equal(B, 0)
test2 = np.any((A_m==B_m).compressed())
และวิธีที่ไร้เดียงสาในการทำงานแรกคือ:
test1 = np.any((np.vstack((A_m[:-1],A_m[:-2],A_m[1:],A_m[2:]))==np.vstack((B_m[1:],B_m[2:],B_m[:-1],B_m[:-2]))).compressed())
เอาต์พุต:
True
True
สำหรับ Test2: คุณสามารถตรวจสอบได้ว่าพวกเขาพบดัชนีที่คล้ายกันที่พบสำหรับค่า 1 หรือไม่
A = np.array([[1, 0, 0, 1],[0, 0, 1, 0],[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 1, 1]])
B = np.array([[0, 0, 0, 0],[0, 0, 0, 0],[1, 1, 0, 0],[0, 0, 1, 0],[0, 1, 0, 1]])
print(len(np.intersect1d(np.flatnonzero(A==1),np.flatnonzero(B==1)))>0))