पांडा समूह में डेटाफ्रेम पंक्तियों को सूची में समूह कैसे बनाएं?


274

मेरे पास एक पांडा डेटा फ्रेम है dfजैसे:

a b
A 1
A 2
B 5
B 5
B 4
C 6

मैं पहले कॉलम द्वारा समूह बनाना चाहता हूं और पंक्तियों में सूची के रूप में दूसरा कॉलम प्राप्त करना चाहता हूं :

A [1,2]
B [5,5,4]
C [6]

क्या पांडा ग्रुपबी का उपयोग करके ऐसा कुछ करना संभव है?

जवाबों:


393

आप इसका उपयोग groupbyब्याज के कॉलम पर समूह के लिए और फिर apply listप्रत्येक समूह में कर सकते हैं:

In [1]: df = pd.DataFrame( {'a':['A','A','B','B','B','C'], 'b':[1,2,5,5,4,6]})
        df

Out[1]: 
   a  b
0  A  1
1  A  2
2  B  5
3  B  5
4  B  4
5  C  6

In [2]: df.groupby('a')['b'].apply(list)
Out[2]: 
a
A       [1, 2]
B    [5, 5, 4]
C          [6]
Name: b, dtype: object

In [3]: df1 = df.groupby('a')['b'].apply(list).reset_index(name='new')
        df1
Out[3]: 
   a        new
0  A     [1, 2]
1  B  [5, 5, 4]
2  C        [6]

7
यह बहुत समय लगता है अगर डेटासेट बड़ा है, तो 10million पंक्तियाँ कहें। क्या ऐसा करने का कोई तेज़ तरीका है? हालांकि, 'ए' में प्राचीन वस्तुओं की संख्या लगभग 500k है
अभिषेक ठाकुर

6
groupby बेहद धीमी और याददाश्त की भूख है, जो आप कर सकते थे, वह कॉलम A द्वारा किया गया था, फिर idxmin और idxmax (संभवतः इसे एक तानाशाही में स्टोर करें) का उपयोग करें और अपने
डेटाफ़्रेम

1
जब मैंने अपनी समस्या के साथ इस समाधान की कोशिश की (समूह और समूह के लिए कई कॉलम होने), तो यह काम नहीं किया - पंडों ने 'फंक्शन कम नहीं किया'। तब मैंने tupleयहां दूसरे उत्तर का अनुसरण किया : stackoverflow.com/questions/19530568/… । स्पष्टीकरण के लिए stackoverflow.com/questions/27439023/… में दूसरा उत्तर देखें ।
एंडरिन

यह समाधान अच्छा है, लेकिन क्या सूची के सेट को स्टोर करने का एक तरीका है, क्या मैं डुप्लिकेट को हटा सकता हूं और फिर इसे स्टोर कर सकता हूं?
श्रीराम अरविंद लक्ष्मणकुमार

1
@PoeteMaudit क्षमा करें, मुझे समझ नहीं आ रहा है कि आप क्या पूछ रहे हैं और टिप्पणियों में प्रश्न पूछ रहे हैं तो SO में खराब फॉर्म है। क्या आप पूछ रहे हैं कि एक सूची में कई कॉलमों को कैसे बदलना है?
एडहूम

47

यदि प्रदर्शन महत्वपूर्ण है, तो खस्ता स्तर तक नीचे जाएं:

import numpy as np

df = pd.DataFrame({'a': np.random.randint(0, 60, 600), 'b': [1, 2, 5, 5, 4, 6]*100})

def f(df):
         keys, values = df.sort_values('a').values.T
         ukeys, index = np.unique(keys, True)
         arrays = np.split(values, index[1:])
         df2 = pd.DataFrame({'a':ukeys, 'b':[list(a) for a in arrays]})
         return df2

टेस्ट:

In [301]: %timeit f(df)
1000 loops, best of 3: 1.64 ms per loop

In [302]: %timeit df.groupby('a')['b'].apply(list)
100 loops, best of 3: 5.26 ms per loop

8
अगर हम केवल दो के .groupby([df.index.month, df.index.day])बजाय दो या दो से अधिक कुंजियों का समूह बना रहे हैं तो हम इसका उपयोग कैसे कर सकते हैं .groupby('a')?
ru111

25

इसे प्राप्त करने का एक आसान तरीका होगा:

df.groupby('a').agg({'b':lambda x: list(x)})

कस्टम एग्रीगेशन लिखते हुए देखें : https://www.kaggle.com/akshaysehgal/how-to-group-by-aggregate-use-py


5
lambda args: f(args)के बराबर हैf
BallpointBen

6
वास्तव में, बस agg(list)पर्याप्त है। यह भी देखें यहाँ
cs95

!! मैं बस कुछ वाक्यविन्यास के लिए गुगली कर रहा था और महसूस किया कि मेरी अपनी नोटबुक को समाधान के लिए संदर्भित किया गया था। इसे लिंक करने के लिए धन्यवाद। बस जोड़ने के लिए, क्योंकि 'सूची' एक श्रृंखला समारोह नहीं है, आपको या तो इसे लागू करने के साथ उपयोग करना होगा df.groupby('a').apply(list)या इसे एक तानाशाह के हिस्से के रूप में उपयोग करना होगा df.groupby('a').agg({'b':list})। आप इसे लैम्ब्डा (जिसे मैं सुझाते हैं) के साथ भी इस्तेमाल कर सकते हैं क्योंकि आप इसके साथ इतना कुछ कर सकते हैं। उदाहरण: df.groupby('a').agg({'c':'first', 'b': lambda x: x.unique().tolist()})जो आपको कोल सी के लिए एक श्रृंखला फ़ंक्शन और एक अद्वितीय फ़ंक्शन को कॉल बी में लागू करने देता है।
अक्षय सहगल

21

जैसा कि आप कह रहे थे कि groupbyएक pd.DataFrameवस्तु की विधि काम कर सकती है।

उदाहरण

 L = ['A','A','B','B','B','C']
 N = [1,2,5,5,4,6]

 import pandas as pd
 df = pd.DataFrame(zip(L,N),columns = list('LN'))


 groups = df.groupby(df.L)

 groups.groups
      {'A': [0, 1], 'B': [2, 3, 4], 'C': [5]}

जो समूहों का विवरण देता है और अनुक्रमित करता है।

उदाहरण के लिए, एकल समूहों के तत्व प्राप्त करने के लिए, आप कर सकते हैं

 groups.get_group('A')

     L  N
  0  A  1
  1  A  2

  groups.get_group('B')

     L  N
  2  B  5
  3  B  5
  4  B  4

21

डेटाफ़्रेम के कई स्तंभों के लिए इसे हल करने के लिए:

In [5]: df = pd.DataFrame( {'a':['A','A','B','B','B','C'], 'b':[1,2,5,5,4,6],'c'
   ...: :[3,3,3,4,4,4]})

In [6]: df
Out[6]: 
   a  b  c
0  A  1  3
1  A  2  3
2  B  5  3
3  B  5  4
4  B  4  4
5  C  6  4

In [7]: df.groupby('a').agg(lambda x: list(x))
Out[7]: 
           b          c
a                      
A     [1, 2]     [3, 3]
B  [5, 5, 4]  [3, 4, 4]
C        [6]        [4]

यह जवाब अनामिका मोदी के जवाब से प्रेरित था । धन्यवाद!


12

निम्नलिखित groupbyऔर aggव्यंजनों में से किसी का उपयोग करें ।

# Setup
df = pd.DataFrame({
  'a': ['A', 'A', 'B', 'B', 'B', 'C'],
  'b': [1, 2, 5, 5, 4, 6],
  'c': ['x', 'y', 'z', 'x', 'y', 'z']
})
df

   a  b  c
0  A  1  x
1  A  2  y
2  B  5  z
3  B  5  x
4  B  4  y
5  C  6  z

सूचियों के रूप में कई स्तंभों को एकत्रित करने के लिए, निम्नलिखित में से किसी एक का उपयोग करें:

df.groupby('a').agg(list)
df.groupby('a').agg(pd.Series.tolist)

           b          c
a                      
A     [1, 2]     [x, y]
B  [5, 5, 4]  [z, x, y]
C        [6]        [z]

केवल एक कॉलम को समूह-सूचीबद्ध करने के लिए, समूह को SeriesGroupByऑब्जेक्ट में कनवर्ट करें, फिर कॉल करें SeriesGroupBy.agg। उपयोग,

df.groupby('a').agg({'b': list})  # 4.42 ms 
df.groupby('a')['b'].agg(list)    # 2.76 ms - faster

a
A       [1, 2]
B    [5, 5, 4]
C          [6]
Name: b, dtype: object

उपरोक्त विधियों कर रहे हैं गारंटी क्रम बनाए रखने के लिए? इसका अर्थ है कि एक ही पंक्ति (लेकिन आपके कोड में अलग-अलग कॉलम, b और c ) के तत्वों के परिणामी सूचियों में एक ही सूचकांक होगा?
काई

@ कै ओह, अच्छा सवाल है। हां और ना। GroupBy ग्रूपर प्रमुख मानों द्वारा आउटपुट को सॉर्ट करता है। हालाँकि यह क्रम सामान्य रूप से स्थिर होता है इसलिए प्रति समूह सापेक्ष सापेक्षता संरक्षित रहती है। सॉर्टिंग व्यवहार को पूरी तरह से अक्षम करने के लिए, उपयोग करें groupby(..., sort=False)। यहाँ, इससे कोई फर्क नहीं पड़ता क्योंकि मैं स्तंभ A पर समूहीकरण कर रहा हूँ जो पहले से ही क्रमबद्ध है।
CS95

मुझे क्षमा करें, मुझे आपका उत्तर समझ नहीं आया। क्या आप और अधिक विस्तार से बता सकते हैं। मुझे लगता है कि यह इस सवाल का हकदार है ..
काई

1
यह बहुत अच्छा जवाब है! क्या सूची के मूल्यों को अद्वितीय बनाने का एक तरीका भी है? कुछ ऐसा हो सकता है। (pd.Series.tolist.unique) शायद?
फेडेरिको

1
@FedericoGentile आप एक लैम्ब्डा का उपयोग कर सकते हैं। यहाँ एक तरीका है:df.groupby('a')['b'].agg(lambda x: list(set(x)))
cs95

7

यदि कई कॉलमों को समूहीकृत करते समय एक अनूठी सूची की तलाश की जा सकती है, तो इससे मदद मिल सकती है:

df.groupby('a').agg(lambda x: list(set(x))).reset_index()

2

df.groupbyसूची और Seriesकंस्ट्रक्टर के साथ उपयोग करें

pd.Series({x : y.b.tolist() for x , y in df.groupby('a')})
Out[664]: 
A       [1, 2]
B    [5, 5, 4]
C          [6]
dtype: object

2

यह उपयोग करने का समय है agg बजायapply

कब

df = pd.DataFrame( {'a':['A','A','B','B','B','C'], 'b':[1,2,5,5,4,6], 'c': [1,2,5,5,4,6]})

यदि आप सूची में कई कॉलम चाहते हैं, तो परिणाम pd.DataFrame

df.groupby('a')[['b', 'c']].agg(list)
# or 
df.groupby('a').agg(list)

यदि आप सूची में एकल कॉलम चाहते हैं, तो परिणाम दें ps.Series

df.groupby('a')['b'].agg(list)
#or
df.groupby('a')['b'].apply(list)

ध्यान दें, परिणामस्वरूप जब आप केवल एकल स्तंभ को एकत्रित करते हैं, pd.DataFrameतो परिणाम के मुकाबले लगभग 10x धीमा होता है ps.Series, इसका उपयोग मल्टीकॉम्पट्स केस में करते हैं।


0

यहाँ मैंने "के साथ तत्वों को समूहीकृत किया है।" एक विभाजक के रूप में

    import pandas as pd

    df = pd.read_csv('input.csv')

    df
    Out[1]:
      Area  Keywords
    0  A  1
    1  A  2
    2  B  5
    3  B  5
    4  B  4
    5  C  6

    df.dropna(inplace =  True)
    df['Area']=df['Area'].apply(lambda x:x.lower().strip())
    print df.columns
    df_op = df.groupby('Area').agg({"Keywords":lambda x : "|".join(x)})

    df_op.to_csv('output.csv')
    Out[2]:
    df_op
    Area  Keywords

    A       [1| 2]
    B    [5| 5| 4]
    C          [6]

0

सबसे आसान तरीका है कि मैंने कम से कम एक कॉलम के लिए अधिकांश समान चीज़ों को प्राप्त नहीं किया है जो कि अनाम फ़ंक्शन के लिए टुपल सिंटैक्स के साथ अनामिका के उत्तर के समान है ।

df.groupby('a').agg(b=('b','unique'), c=('c','unique'))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.