स्तंभों से मेल खाने के लिए पांडा डेटा फ़्रेम में डेटा का उपयोग करें


18

मेरे पास दो pandasडेटा फ़्रेम हैं, aऔर b:

a1   a2   a3   a4   a5   a6   a7
1    3    4    5    3    4    5
0    2    0    3    0    2    1
2    5    6    5    2    1    2

तथा

b1   b2   b3   b4   b5   b6   b7
3    5    4    5    1    4    3
0    1    2    3    0    0    2
2    2    1    5    2    6    5

दो डेटा फ़्रेम में समान डेटा होते हैं, लेकिन एक अलग क्रम में और विभिन्न स्तंभ नामों के साथ। दो डेटा फ्रेम में संख्या के आधार पर, मैं में प्रत्येक स्तंभ नाम से मेल करने में सक्षम होना चाहते हैं aमें प्रत्येक स्तंभ नाम के b

यह उतना आसान नहीं है जितना कि पहली पंक्ति के aसाथ पहली पंक्ति की तुलना करना जैसे bकि डुप्लिकेट किए गए मान हैं, उदाहरण के लिए दोनों a4और a7मूल्य हैं 5इसलिए उन्हें तुरंत b2या तो मेल करना संभव नहीं है b4

इसे करने का बेहतरीन तरीका क्या है?

जवाबों:


16

यहाँ एक तरीका है sort_values:

m=df1.T.sort_values(by=[*df1.index]).index
n=df2.T.sort_values(by=[*df2.index]).index
d=dict(zip(m,n))
print(d)

{'a1': 'b5', 'a5': 'b1', 'a2': 'b7', 'a3': 'b6', 'a6': 'b3', 'a7': 'b2', 'a4': 'b4'}

अच्छा आदेश साझा करने के लिए धन्यवाद Anky, क्या आप कृपया [*df1.index]भाग पर अधिक बता सकते हैं ? आपका आभारी रहूंगा, खुश होऊंगा।
रविंदरसिंह

1
@ RavinderSingh13 ज़रूर, sort_values(by=..)एक सूची को एक पैरामीटर के रूप में लेता है इसलिए मैं यहाँ एक सूची के लिए सूचकांक को अनपैक कर रहा हूं, आप भी कर सकते हैं :) के list(df1.index)बजाय[*df1.index]
aky

16

यहाँ एक तरह से लीची का सेवन किया गया है broadcasting:

b_cols = b.columns[(a.values == b.T.values[...,None]).all(1).argmax(1)]
dict(zip(a, b_cols))

{'a1': 'b5',
 'a2': 'b7',
 'a3': 'b6',
 'a4': 'b4',
 'a5': 'b1',
 'a6': 'b3',
 'a7': 'b2'}

एक अन्य समान दृष्टिकोण (@piR द्वारा):

a_ = a.to_numpy()
b_ = b.to_numpy()
i, j = np.where((a_[:, None, :] == b_[:, :, None]).all(axis=0))
dict(zip(a.columns[j], b.columns[i]))

{'a1': 'b5',
 'a2': 'b7',
 'a3': 'b6',
 'a4': 'b4',
 'a5': 'b1',
 'a6': 'b3',
 'a7': 'b2'}

1
मैंने अपनी नाक आपकी पोस्ट में चिपका दी। उम्मीद है, आपको कोई आपत्ति नहीं है। कृपया इसे अपनी पसंद के अनुसार बदलें।
13:13

आह विपरीत :) अच्छा दृष्टिकोण, और बड़े dataframes पर जाँच पर यह थोड़ा बेहतर बनाता प्रदर्शन @piRSquared
yatu

12

का एक तरीका merge

s=df1.T.reset_index().merge(df2.T.assign(match=lambda x : x.index))
dict(zip(s['index'],s['match']))
{'a1': 'b5', 'a2': 'b7', 'a3': 'b6', 'a4': 'b4', 'a5': 'b1', 'a6': 'b3', 'a7': 'b2'}

मैंने सोचा कि मैं एक और चतुर समाधान केवल यह देखने के लिए
जोड़ूंगा

8

शब्दकोश समझ

tupleएक शब्दकोश में हैश कीज़ के रूप में कॉलम मानों का उपयोग करें

d = {(*t,): c for c, t in df2.items()}
{c: d[(*t,)] for c, t in df1.items()}

{'a1': 'b5',
 'a2': 'b7',
 'a3': 'b6',
 'a4': 'b4',
 'a5': 'b1',
 'a6': 'b3',
 'a7': 'b2'}

बस अगर हमारे पास सही प्रतिनिधित्व नहीं है, तो मैंने केवल उन स्तंभों के लिए शब्दकोश तैयार किया है जहां एक मैच है।

d2 = {(*t,): c for c, t in df2.items()}
d1 = {(*t,): c for c, t in df1.items()}

{d1[c]: d2[c] for c in {*d1} & {*d2}}

{'a5': 'b1',
 'a2': 'b7',
 'a7': 'b2',
 'a6': 'b3',
 'a3': 'b6',
 'a1': 'b5',
 'a4': 'b4'}

idxmax

बेतुके पर यह सीमाएँ ... वास्तव में ऐसा मत करो।

{c: df2.T.eq(df1[c]).sum(1).idxmax() for c in df1}

{'a1': 'b5',
 'a2': 'b7',
 'a3': 'b6',
 'a4': 'b4',
 'a5': 'b1',
 'a6': 'b3',
 'a7': 'b2'}

1
यह कैसा है, मैं इन बयानों में प्रत्येक अभिव्यक्ति को समझ सकता हूं, फिर भी पूरी तरह से मेरे सिर में नहीं देख सकता कि वास्तव में यहां क्या हो रहा है? शतरंज की तरह किंडा, मुझे पता है कि बोर्ड पर सभी टुकड़े को कैसे स्थानांतरित करना है, लेकिन अधिक नहीं देख सकते हैं कि 2 आगे बढ़ते हैं।
स्कॉट बोस्टन

ठीक है ... मैंने इसे अभी पचा लिया है और यह अभी पूरी तरह से शानदार है। +1
स्कॉट बोस्टन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.