2015-09-24 15 views
5

में प्रत्येक पंक्ति में गैर-शून्य मानों के लिए कॉलम इंडेक्स का सेट ढूंढें क्या पांडा के डेटा फ्रेम में प्रत्येक पंक्ति में गैर-शून्य मानों के लिए कॉलम इंडेक्स के सेट को खोजने का कोई अच्छा तरीका है? क्या मुझे डेटा फ्रेम पंक्ति-दर-पंक्ति को पार करना है?पांडा के डेटा फ्रेम

उदाहरण के लिए, डेटा फ्रेम ढेर

c1 c2 c3 c4 c5 c6 c7 c8 c9 
1 1 0 0 0 0 0 0 0 
1 0 0 0 0 0 0 0 0 
0 1 0 0 0 0 0 0 0 
1 0 0 0 0 0 0 0 0 
0 1 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 2 1 1 1 1 1 0 2 
1 5 5 0 0 1 0 4 6 
4 3 0 1 1 1 1 5 10 
3 5 2 4 1 2 2 1 3 
6 4 0 1 0 0 0 0 0 
3 9 1 0 1 0 2 1 0 

उत्पादन

['c1','c2'] 
['c1'] 
['c2'] 
... 

उत्तर

5

ऐसा लगता है कि आपको डेटाफ्रेम को पंक्ति से पार करना होगा।

cols = df.columns 
bt = df.apply(lambda x: x > 0) 
bt.apply(lambda x: list(cols[x.values]), axis=1) 

और आप मिल जाएगा:

0         [c1, c2] 
1          [c1] 
2          [c2] 
3          [c1] 
4          [c2] 
5          [] 
6    [c2, c3, c4, c5, c6, c7, c9] 
7     [c1, c2, c3, c6, c8, c9] 
8   [c1, c2, c4, c5, c6, c7, c8, c9] 
9  [c1, c2, c3, c4, c5, c6, c7, c8, c9] 
10       [c1, c2, c4] 
11    [c1, c2, c3, c5, c7, c8] 
dtype: object 

यदि प्रदर्शन बात है, नीचे की तरह बूलियन DataFrame निर्माण के लिए raw=True पारित करने के लिए प्रयास करें:

%timeit df.apply(lambda x: x > 0, raw=True).apply(lambda x: list(cols[x.values]), axis=1) 
1000 loops, best of 3: 812 µs per loop 

यह आपको एक बेहतर प्रदर्शन लाभ लाता है। बाद raw=False है परिणाम (जो डिफ़ॉल्ट है):

%timeit df.apply(lambda x: x > 0).apply(lambda x: list(cols[x.values]), axis=1) 
100 loops, best of 3: 2.59 ms per loop 
1

संभावित एक बेहतर डेटा संरचना (बल्कि सूचियों का एक श्रृंखला की तुलना में) होने की उम्मीद है है है:

In [11]: res = df[df!=0].stack() 

In [12]: res 
Out[12]: 
0 c1  1 
    c2  1 
1 c1  1 
2 c2  1 
3 c1  1 
... 

और आप मूल पंक्तियों पर फिर से सक्रिय हो सकते हैं:

In [13]: res.loc[0] 
Out[13]: 
c1 1 
c2 1 
dtype: float64 

In [14]: res.loc[0].index 
Out[14]: Index(['c1', 'c2'], dtype='object') 

नोट: मैंने सोचा था कि आप में एक सूची वापस जाने के लिए सक्षम होने के लिए इस्तेमाल किया एक लागू अब यह मामला प्रतीत होता है (एक DataFrame जो सूची तत्व है बनाने के लिए)।

2
कैसे इस दृष्टिकोण के बारे में

?

#create a True/False data frame 
df_boolean = df>0 

#a little helper method that uses boolean slicing internally 
def bar(x,columns): 
    return ','.join(list(columns[x])) 

#use an apply along the column axis 
df_boolean['result'] = df_boolean.apply(lambda x: bar(x,df_boolean.columns),axis=1) 

# filter out the empty "rows" adn grab the result column 
df_result = df_boolean[df_boolean['result'] != '']['result'] 

#append an axis, just so each line will will output a list 
lst_result = df_result.values[:,np.newaxis] 

print '\n'.join([ str(myelement) for myelement in lst_result]) 

और इस का उत्पादन:

['c1,c2'] 
['c1'] 
['c2'] 
['c1'] 
['c2'] 
['c2,c3,c4,c5,c6,c7,c9'] 
['c1,c2,c3,c6,c8,c9'] 
['c1,c2,c4,c5,c6,c7,c8,c9'] 
['c1,c2,c3,c4,c5,c6,c7,c8,c9'] 
['c1,c2,c4'] 
['c1,c2,c3,c5,c7,c8'] 
+0

Scari मुझे यह करने के लिए और अधिक संक्षिप्त समाधान के साथ हरा चुका है। आउटपुट लिखने या हटाने के लिए खुश करने के लिए मैं अपना जवाब ऑनलाइन छोड़ सकता हूं। – Dickster

संबंधित मुद्दे