প্যানডাস গ্রুপবাইয়ের তালিকাতে ডাটাফ্রেম সারিগুলিকে কীভাবে গ্রুপ করবেন?


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
যদি ডেটাসেটটি বিশাল হয় তবে এটি অনেক সময় নেয় 10 মিলিয়ন সারি বলুন। এটি করার কোনও দ্রুত উপায় আছে? 'ক' তে অদ্ভুত সংখ্যা অবশ্য 500 কে প্রায়
অভিষেক ঠাকুর

6
গ্রুপবাই কুখ্যাতভাবে ধীর এবং স্মৃতির ক্ষুধার্ত, আপনি যা করতে পারতেন তা কলাম A অনুসারে বাছাই করুন, তারপরে idxmin এবং idxmax খুঁজুন (সম্ভবত এটি একটি ডিকের মধ্যে সংরক্ষণ করুন) এবং আপনার ডেটা ফ্রেমের টুকরো টুকরো করার জন্য এটি ব্যবহার করুন আমার মনে হয়
এডচাম

1
আমি যখন আমার সমস্যার সাথে এই সমাধানটি চেষ্টা করেছি (গ্রুপবি ও গ্রুপে একাধিক কলাম রয়েছে) তখন এটি কার্যকর হয়নি - পান্ডে পাঠানো হয়েছিল 'ফাংশন হ্রাস করে না' sent তারপরে আমি tupleএখানে দ্বিতীয় উত্তরটি অনুসরণ করে ব্যবহার করেছি : stackoverflow.com/questions/19530568/… । ব্যাখ্যার জন্য স্ট্যাকওভারফ্লো / প্রশ্ন / ২2৪৩৯০২০ / ২-এ দ্বিতীয় উত্তর দেখুন ।
আন্দারিন

এই সমাধানটি ভাল, তবে তালিকার সেটটি সংরক্ষণ করার কোনও উপায় আছে, যার অর্থ আমি নকলগুলি সরিয়ে আবার এটি সঞ্চয় করতে পারি?
শ্রীরাম অরবিন্দ লক্ষ্মণকুমার

1
@ পোয়েটমাউডিট দুঃখিত দুঃখিত আপনি কী জিজ্ঞাসা করছেন এবং মন্তব্যে প্রশ্ন জিজ্ঞাসা করছেন তা এসও এর ফর্ম রূপ। আপনি কি জিজ্ঞাসা করছেন কীভাবে একক তালিকায় একাধিক কলাম যুক্ত করতে?
এডচুম

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')?
রু 111

25

এটি অর্জনের একটি সহজ উপায় হ'ল:

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

কাস্টম সমষ্টিগুলিকে লেখার জন্য দেখুন: https://www.kaggle.com/akshaysehgal/how-to-group-by-aggregate- using-py


5
lambda args: f(args)সমতুল্যf
বলপয়েন্টবেন

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

উপরের পদ্ধতিগুলি কি সংরক্ষণের জন্য গ্যারান্টিযুক্ত ? মানে একই সারি থেকে আসা উপাদানগুলি (তবে উপরের কোডে বিভিন্ন কলাম, বি এবং সি ) ফলাফলের তালিকায় একই সূচক থাকবে?
কাই

@ কাই ওহ, ভাল প্রশ্ন। হ্যা এবং না. গ্রুপবি গ্রাইপার কী মান অনুসারে আউটপুট সাজায়। তবে বাছাইটি সাধারণত স্থিতিশীল তাই গ্রুপ অনুসারে আপেক্ষিক অর্ডার সংরক্ষণ করা হয়। সম্পূর্ণরূপে বাছাইয়ের আচরণটি অক্ষম করতে, ব্যবহার করুন groupby(..., sort=False)। এখানে, এটি কোনও পার্থক্য করবে না যেহেতু আমি কলাম A এ ভাগ করছি যা ইতিমধ্যে সাজানো হয়েছে।
CS95

আমি দুঃখিত, আমি আপনার উত্তর বুঝতে পারি না। আপনি আরও বিস্তারিতভাবে ব্যাখ্যা করতে পারেন। আমি মনে করি এটি নিজের প্রশ্নের দাবিদার ..
কাই

1
এটি একটি খুব ভাল উত্তর! তালিকার মানগুলি অনন্য করে তোলার কোনও উপায় আছে কি? .agg (pd.Series.tolist.unique) এর মতো কিছু হতে পারে?
ফেডেরিকো

1
@ ফেডেরিকোজেন্তেল আপনি একটি ল্যাম্বডা ব্যবহার করতে পারেন। এখানে একটি উপায়: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আপনি ps.Seriesযখন একক কলামটি কেবলমাত্র একত্রিত করেন , ফলাফলটি ফলাফলের তুলনায় প্রায় 10x ধীর হয় , এটি মাল্টিকালামস ক্ষেত্রে ব্যবহার করুন।


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

কমপক্ষে একটি কলামের জন্য একই জিনিসটির বেশিরভাগ অর্জন আমি দেখতে পাচ্ছি না যা সম্পূর্ণ ফাংশনের জন্য টিউপল সিনট্যাক্সের সাথে অনামিকার উত্তরের মতো similar

df.groupby('a').agg(b=('b','unique'), c=('c','unique'))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.