2017-01-10 8 views
7

में अपने मूल्यों के साथ स्तंभ शीर्षकों के एक समूह स्वैप करने के लिए मैं निम्नलिखित डेटा फ्रेम है:कैसे पांडा

a1 | a2 | a3 | a4 
--------------------- 
Bob | Cat | Dov | Edd 
Cat | Dov | Bob | Edd 
Edd | Cat | Dov | Bob 

और मैं इसे करने के लिए

Bob | Cat | Dov | Edd 
--------------------- 
a1 | a2 | a3 | a4 
a3 | a1 | a2 | a4 
a4 | a2 | a3 | a1 

नोट कनवर्ट करना चाहते हैं कि स्तंभों की संख्या अद्वितीय मानों की संख्या के बराबर है, और पंक्तियों की संख्या और क्रम

उत्तर

9

1) आवश्यक दृष्टिकोण:

एक तेजी से कार्यान्वयन dataframe के मूल्यों को सॉर्ट और स्तंभों तदनुसार उस पर आधारित संरेखित करने के लिए किया जाएगा np.argsort के बाद सूचकांक प्राप्त है।

df.columns[np.argsort(df.values)] 
Out[156]: 
Index([['a1', 'a2', 'a3', 'a4'], ['a3', 'a1', 'a2', 'a4'], 
     ['a4', 'a2', 'a3', 'a1']], 
     dtype='object') 

2) धीरे सामान्यीकृत दृष्टिकोण:

pd.DataFrame(df.columns[np.argsort(df.values)], df.index, np.unique(df.values)) 

enter image description here

लागू करने np.argsort हमें डेटा हम देख रहे देता हैकुछ गति/दक्षता की लागत पर अधिक सामान्यीकृत दृष्टिकोण apply का उपयोग dict डेटाफ्रेम में उनके संबंधित कॉलम नामों के साथ मौजूद स्ट्रिंग/मानों के मैपिंग के बाद करना होगा।

प्राप्त श्रृंखला को उनके list प्रतिनिधित्व में कनवर्ट करने के बाद बाद में डेटाफ्रेम कन्स्ट्रक्टर का उपयोग करें।

pd.DataFrame(df.apply(lambda s: dict(zip(pd.Series(s), pd.Series(s).index)), 1).tolist()) 

3) तेज़ सामान्यीकृत दृष्टिकोण:

शब्दकोशों की एक सूची प्राप्त करने df.to_dict + orient='records' से के बाद, हम उस संबंधित कुंजी और मान जोड़े के समय में उन के माध्यम से पुनरावृत्ति स्वैप करने के लिए की जरूरत है एक लूप।

pd.DataFrame([{val:key for key, val in d.items()} for d in df.to_dict('r')]) 

नमूना परीक्षण का मामला:

df = df.assign(a5=['Foo', 'Bar', 'Baz']) 

दोनों इन तरीकों का उत्पादन:

enter image description here


@piRSquared संपादित

सामान्यीकृत समाधान

def nic(df): 
    v = df.values 
    n, m = v.shape 
    u, inv = np.unique(v, return_inverse=1) 
    i = df.index.values 
    c = df.columns.values 
    r = np.empty((n, len(u)), dtype=c.dtype) 
    r[i.repeat(m), inv] = np.tile(c, n) 
    return pd.DataFrame(r, i, u) 

मैं आधारित एक बहुत तेजी से और सामान्यीकृत numpy के साथ आ के लिए @piRSquared उपयोगकर्ता धन्यवाद देना चाहते हैं वैकल्पिक सोलन

+1

ध्यान दें कि यह केवल विशेष परिस्थितियों में काम करता है जहां सब कुछ अच्छी तरह से प्रतिनिधित्व किया जाता है। यह एक अच्छा जवाब है, मैं बस इसे – piRSquared

+1

धन्यवाद बता रहा हूं। मुझे लगता है कि ओपी ने अपने पद के निचले हिस्से में यह मामला दर्ज किया था। अन्यथा, यदि सभी कॉलम समान रूप से प्रदर्शित नहीं होते हैं, तो मुझे लगता है कि यह असफल हो जाएगा। –

+0

यह समझ में आता है – piRSquared

5

आप इसे स्टैक के साथ दोबारा बना सकते हैं और मूल्यों और अनुक्रमणिका के स्वैपिंग के साथ अनस्टैक कर सकते हैं:

df_swap = (df.stack()      # reshape the data frame to long format 
      .reset_index(level = 1)  # set the index(column headers) as a new column 
      .set_index(0, append=True) # set the values as index 
      .unstack(level=1))   # reshape the data frame to wide format 

df_swap.columns = df_swap.columns.get_level_values(1) # drop level 0 in the column index 
df_swap 

enter image description here

+1

मेरा मानना ​​है कि 'to_frame' की आवश्यकता नहीं है, के रूप में' reset_index' एक dataframe देता है। – IanS

+0

त्वरित प्रतिक्रिया के लिए धन्यवाद और स्पष्टीकरण के लिए धन्यवाद :) – edmondawad

1

numpy + pandas

v = df.values 
n, m = v.shape 
i = df.index.values 
c = df.columns.values 

# create series with values that were column values 
# create multi index with first level from existing index 
# and second level from flattened existing values 
# then unstack 
pd.Series(
    np.tile(c, n), 
    [i.repeat(m), v.ravel()] 
).unstack() 

    Bob Cat Dov Edd 
0 a1 a2 a3 a4 
1 a3 a1 a2 a4 
2 a4 a2 a3 a1