গোষ্ঠী ব্যবহার করে গোষ্ঠীতে সর্বাধিক গণনা রয়েছে এমন সারি (গুলি) পান


244

কলাম countদ্বারা গোষ্ঠীভুক্ত হওয়ার পরে কলামের সর্বাধিক মান থাকা পান্ডাস ডাটাফ্রেমে আমি কীভাবে সমস্ত সারি সন্ধান করব ['Sp','Mt']?

উদাহরণ 1: নিম্নলিখিত ডেটা ফ্রেম, যা আমি গ্রুপ করি ['Sp','Mt']:

   Sp   Mt Value   count
0  MM1  S1   a      **3**
1  MM1  S1   n      2
2  MM1  S3   cb     5
3  MM2  S3   mk      **8**
4  MM2  S4   bg     **10**
5  MM2  S4   dgd      1
6  MM4  S2  rd     2
7  MM4  S2   cb      2
8  MM4  S2   uyi      **7**

প্রত্যাশিত আউটপুট: ফলাফলগুলির সারিগুলি পান যার গোষ্ঠীগুলির মধ্যে সর্বাধিক, যেমন:

0  MM1  S1   a      **3**
1 3  MM2  S3   mk      **8**
4  MM2  S4   bg     **10** 
8  MM4  S2   uyi      **7**

উদাহরণ 2: এই ডেটাফ্রেম, যা আমি গ্রুপ করি ['Sp','Mt']:

   Sp   Mt   Value  count
4  MM2  S4   bg     10
5  MM2  S4   dgd    1
6  MM4  S2   rd     2
7  MM4  S2   cb     8
8  MM4  S2   uyi    8

উপরের উদাহরণস্বরূপ, আমি সমস্তcount গ্রুপ সর্বাধিক সমান যেখানে প্রতিটি গ্রুপে পেতে চাই :

MM2  S4   bg     10
MM4  S2   cb     8
MM4  S2   uyi    8

আপনার ডেটা ফ্রেমটি কোন ফর্ম্যাটে রয়েছে?
ডেভিড রবিনসন

2
আমি পাই না। একটি গ্রুপ ঠিক কি? ফলাফলের দ্বিতীয় লাইনটি কেন শুরু হয় 1 3?
জো সো

stackoverflow.com/questions/18879782/... উপযোগী হতে গেল
J_Arthur

1
এই উত্তরটি দ্রুততম সমাধান আমি খুঁজে পাইনি হল: stackoverflow.com/a/21007047/778533
tommy.carstensen

এই প্রশ্নের অনুরূপ, যে কেউ দয়া করে এর উত্তর দিতে পারে: stackoverflow.com/questions/62069465/… ধন্যবাদ।
ds_Abc

উত্তর:


325
In [1]: df
Out[1]:
    Sp  Mt Value  count
0  MM1  S1     a      3
1  MM1  S1     n      2
2  MM1  S3    cb      5
3  MM2  S3    mk      8
4  MM2  S4    bg     10
5  MM2  S4   dgd      1
6  MM4  S2    rd      2
7  MM4  S2    cb      2
8  MM4  S2   uyi      7

In [2]: df.groupby(['Mt'], sort=False)['count'].max()
Out[2]:
Mt
S1     3
S3     8
S4    10
S2     7
Name: count

মূল ডিএফের সূচকগুলি পেতে আপনি করতে পারেন:

In [3]: idx = df.groupby(['Mt'])['count'].transform(max) == df['count']

In [4]: df[idx]
Out[4]:
    Sp  Mt Value  count
0  MM1  S1     a      3
3  MM2  S3    mk      8
4  MM2  S4    bg     10
8  MM4  S2   uyi      7

মনে রাখবেন যে প্রতি গ্রুপে একাধিক সর্বোচ্চ মান থাকলে, সমস্তই ফিরে আসবে।

হালনাগাদ

শিলাবৃষ্টিতে ম্যারি সুযোগে ওপি অনুরোধ করছে:

In [5]: df['count_max'] = df.groupby(['Mt'])['count'].transform(max)

In [6]: df
Out[6]:
    Sp  Mt Value  count  count_max
0  MM1  S1     a      3          3
1  MM1  S1     n      2          3
2  MM1  S3    cb      5          8
3  MM2  S3    mk      8          8
4  MM2  S4    bg     10         10
5  MM2  S4   dgd      1         10
6  MM4  S2    rd      2          7
7  MM4  S2    cb      2          7
8  MM4  S2   uyi      7          7

@ জেলাজনি,, কোনও কলাম দ্বারা দলবদ্ধকরণের জন্য এবং তারপরে ২ টি কলাম দেখে এবং এর থেকে আরও একটির জন্য আরও দুটি করার জন্য এই উত্তরটি গ্রহণ করার কী উপায় আছে? আমি এটা কাজ করতে পারি না। আমার বর্তমানে যা আছে তা হ'ল: ডিফ গ্রেটার (মার্জ, সর্বাধিকআ, সর্বাধিক বি): a = মার্জ [সর্বাধিকআ] বি = মার্জ [সর্বাধিক]] রিটার্ন সর্বাধিক (ক, খ) মার্জার.groupby ("অনুসন্ধান_কর্ম") প্রয়োগ করুন (গ্রেটার, "অনুপাত_ x) "," অনুপাত_ওয়াই ")
ম্যাথলভার

3
@ জেলাজনি I'm আমি দ্বিতীয়টি ব্যবহার করছি idxapproach তবে, আমি প্রতিটি গ্রুপের জন্য কেবলমাত্র একক সর্বোচ্চ বহন করতে পারি (এবং আমার ডেটাতে কয়েকটি সদৃশ-ম্যাক্স রয়েছে)। আপনার সমাধান সঙ্গে এই কাছাকাছি পেতে একটি উপায় আছে?
পিট

আসলে, এটি আমার পক্ষে কাজ করে না। আমি সমস্যাটি ধরে রাখতে পারি না, কারণ ডেটাফ্রেম যদি বড় ছেড়ে যায় তবে @ রানির সমাধানটি ভাল কাজ করে
লাডেনকোভ ভ্লাদিস্লাভ

হাই জিলেজনি, আমি যদি একটি সর্বোচ্চ মানের পরিবর্তে শীর্ষ 3 সর্বোচ্চ সারি নিতে চাই, আমি কীভাবে আপনার কোডটি টুইট করতে পারি?
জেফির

transformপদ্ধতিতে পুলের পারফরম্যান্স থাকতে পারে যখন ডেটা সেট যথেষ্ট বড় হয়, প্রথমে সর্বাধিক মান পান তারপরে ডেটাফ্রেমগুলি মার্জ করা ভাল হবে।
উডস চেন

169

আপনি গণনা অনুসারে ডেটা ফ্রেমকে বাছাই করতে পারেন এবং তারপরে নকলগুলি সরিয়ে ফেলতে পারেন। আমি মনে করি এটি সহজ:

df.sort_values('count', ascending=False).drop_duplicates(['Sp','Mt'])

4
খুব সুন্দর! লার্জি ফ্রেম (25 কে সারি) সহ দ্রুত
নোলান কনওয়ে

2
পাইথনের সাথে যারা কিছুটা নতুন, আপনার এটি একটি নতুন ভেরিয়েবলের জন্য নির্ধারণ করা দরকার, এটি বর্তমান ডিএফ ভেরিয়েবল পরিবর্তন করে না।
টাইলার

1
@ সমীর বা inplace = Trueযুক্তি হিসাবে ব্যবহার করুনdrop_duplicates
টিএমআরটিস্মিথ

5
এটি একই সর্বাধিক মানগুলির সাথে সারিগুলির মধ্যে একটির প্রয়োজন হলে এটি একটি দুর্দান্ত উত্তর, তবে এটি যদি সর্বাধিক মান সহ সমস্ত সারি প্রয়োজন আমার প্রত্যাশায় কাজ করবে না।
উডস চেন

1
@ উডসচেন, এটি [এসপি, এমটি] এর সদৃশগুলি ফেলেছে, সুতরাং আপনার উদাহরণে আউটপুটটি কেবল এক সারি হওয়া উচিত।
রানী

54

সহজ সমাধান প্রয়োগ করা হবে: সর্বাধিক মান সহ সারি সূচক পেতে idxmax () ফাংশন। এটি গ্রুপে সর্বাধিক মান সহ সমস্ত সারি ফিল্টার করবে।

In [365]: import pandas as pd

In [366]: df = pd.DataFrame({
'sp' : ['MM1', 'MM1', 'MM1', 'MM2', 'MM2', 'MM2', 'MM4', 'MM4','MM4'],
'mt' : ['S1', 'S1', 'S3', 'S3', 'S4', 'S4', 'S2', 'S2', 'S2'],
'val' : ['a', 'n', 'cb', 'mk', 'bg', 'dgb', 'rd', 'cb', 'uyi'],
'count' : [3,2,5,8,10,1,2,2,7]
})

In [367]: df                                                                                                       
Out[367]: 
   count  mt   sp  val
0      3  S1  MM1    a
1      2  S1  MM1    n
2      5  S3  MM1   cb
3      8  S3  MM2   mk
4     10  S4  MM2   bg
5      1  S4  MM2  dgb
6      2  S2  MM4   rd
7      2  S2  MM4   cb
8      7  S2  MM4  uyi


### Apply idxmax() and use .loc() on dataframe to filter the rows with max values:
In [368]: df.loc[df.groupby(["sp", "mt"])["count"].idxmax()]                                                       
Out[368]: 
   count  mt   sp  val
0      3  S1  MM1    a
2      5  S3  MM1   cb
3      8  S3  MM2   mk
4     10  S4  MM2   bg
8      7  S2  MM4  uyi

### Just to show what values are returned by .idxmax() above:
In [369]: df.groupby(["sp", "mt"])["count"].idxmax().values                                                        
Out[369]: array([0, 2, 3, 4, 8])

4
প্রশ্নকারী এখানে নিদিষ্ট "I want to get ALL the rows where count equals max in each group", যখন idxmax Return[s] index of first occurrence of maximum over requested axis"ডক্স (0.21) অনুযায়ী।
সর্বোচ্চ শক্তি

1
এটি দুর্দান্ত সমাধান, তবে ভিন্ন সমস্যার জন্য
কার্লোস সুজা

33

অপেক্ষাকৃত বড় ডেটাফ্রেমে (~ 400k সারি) জেলাজ্নির প্রস্তাবিত সমাধানটি চেষ্টা করে দেখতে পেলাম যে এটি খুব ধীর হয়েছে। এখানে একটি বিকল্প যা আমি আমার ডেটা সেটে দ্রুততার অর্ডারগুলি দ্রুত চালাতে পেয়েছি।

df = pd.DataFrame({
    'sp' : ['MM1', 'MM1', 'MM1', 'MM2', 'MM2', 'MM2', 'MM4', 'MM4', 'MM4'],
    'mt' : ['S1', 'S1', 'S3', 'S3', 'S4', 'S4', 'S2', 'S2', 'S2'],
    'val' : ['a', 'n', 'cb', 'mk', 'bg', 'dgb', 'rd', 'cb', 'uyi'],
    'count' : [3,2,5,8,10,1,2,2,7]
    })

df_grouped = df.groupby(['sp', 'mt']).agg({'count':'max'})

df_grouped = df_grouped.reset_index()

df_grouped = df_grouped.rename(columns={'count':'count_max'})

df = pd.merge(df, df_grouped, how='left', on=['sp', 'mt'])

df = df[df['count'] == df['count_max']]

1
সত্যিই এটি অনেক দ্রুত। রূপান্তরটি বড় ডেটাসেটের জন্য ধীর বলে মনে হচ্ছে।
Goh

1
প্রতিটি লাইন কী করে তা বোঝাতে আপনি মন্তব্য যুক্ত করতে পারেন?
tommy.carstensen

fww: আমি @ জেলাজনি 7 এর থেকে আরও মার্জিত-সন্ধানী সমাধানটি পেয়েছি আমার 100k K সারিগুলির সেটটি নির্বাহ করতে দীর্ঘ সময় নিয়েছে, তবে এইটি বেশ দ্রুত চলেছে ran (আমি এখনই চলতে চলেছি 0.13.0, যা স্বচ্ছলতার জন্য দায়ী হতে পারে)।
রোল্যান্ড 21

2
তবে এটি করার ফলে df[df['count'] == df['count_max']]NaN সারিগুলি, পাশাপাশি উপরের উত্তরগুলিও হারাবে।
কিউ জুও

আমি এই পদ্ধতির ব্যবহারের জন্য অত্যন্ত পরামর্শ দিচ্ছি, বড় ডেটা ফ্রেমের জন্য .appy () বা .agg () ব্যবহার করা খুব দ্রুত।
তোয়া ডি সার্ডান

18

আপনার দ্বারা sort_values+ ব্যবহার করে গোষ্ঠীটি করার দরকার নেইdrop_duplicates

df.sort_values('count').drop_duplicates(['Sp','Mt'],keep='last')
Out[190]: 
    Sp  Mt Value  count
0  MM1  S1     a      3
2  MM1  S3    cb      5
8  MM4  S2   uyi      7
3  MM2  S3    mk      8
4  MM2  S4    bg     10

ব্যবহার করে প্রায় একই যুক্তি tail

df.sort_values('count').groupby(['Sp', 'Mt']).tail(1)
Out[52]: 
    Sp  Mt Value  count
0  MM1  S1     a      3
2  MM1  S3    cb      5
8  MM4  S2   uyi      7
3  MM2  S3    mk      8
4  MM2  S4    bg     10

এটি কেবলমাত্র অন্যান্য সমাধানগুলির চেয়ে তাত্পর্যপূর্ণ ক্রম নয় (কমপক্ষে আমার ব্যবহারের ক্ষেত্রে) এটির মূল ডেটাফ্রেম নির্মাণের অংশ হিসাবে কেবল শৃঙ্খলাবদ্ধ হওয়ার অতিরিক্ত সুবিধা রয়েছে।
ক্লে

আমি আমার মাথা আঁচড়ান এই কথা ভেবে নিশ্চয়ই এটি সহজ, বরাবর মিঃ ওয়েনের মতো আপনার উজ্জ্বল উত্তরের জন্য ধন্যবাদ for
দাতানোভিস

7

আমার জন্য, সবচেয়ে সহজ সমাধান হ'ল মূল্য রাখি যখন গণনা সর্বাধিকের সমান হয়। সুতরাং, নিম্নলিখিত এক লাইন কমান্ড যথেষ্ট:

df[df['count'] == df.groupby(['Mt'])['count'].transform(max)]

4

ব্যবহার groupbyএবং idxmaxপদ্ধতি:

  1. কর্নেল স্থানান্তর dateকরুন datetime:

    df['date']=pd.to_datetime(df['date'])
  2. পরে maxকলামের সূচি পান :dategroupyby ad_id

    idx=df.groupby(by='ad_id')['date'].idxmax()
  3. পছন্দসই ডেটা পান:

    df_max=df.loc[idx,]

আউট [54]:

ad_id  price       date
7     22      2 2018-06-11
6     23      2 2018-06-22
2     24      2 2018-06-30
3     28      5 2018-06-22

2
df = pd.DataFrame({
'sp' : ['MM1', 'MM1', 'MM1', 'MM2', 'MM2', 'MM2', 'MM4', 'MM4','MM4'],
'mt' : ['S1', 'S1', 'S3', 'S3', 'S4', 'S4', 'S2', 'S2', 'S2'],
'val' : ['a', 'n', 'cb', 'mk', 'bg', 'dgb', 'rd', 'cb', 'uyi'],
'count' : [3,2,5,8,10,1,2,2,7]
})

df.groupby(['sp', 'mt']).apply(lambda grp: grp.nlargest(1, 'count'))

2

বুঝতে "প্রয়োগ" "nlargest" করার বস্তু groupby ঠিক যেমন কাজ করে :

অতিরিক্ত সুবিধা - প্রয়োজনে শীর্ষ এন মানগুলিও আনতে পারে :

In [85]: import pandas as pd

In [86]: df = pd.DataFrame({
    ...: 'sp' : ['MM1', 'MM1', 'MM1', 'MM2', 'MM2', 'MM2', 'MM4', 'MM4','MM4'],
    ...: 'mt' : ['S1', 'S1', 'S3', 'S3', 'S4', 'S4', 'S2', 'S2', 'S2'],
    ...: 'val' : ['a', 'n', 'cb', 'mk', 'bg', 'dgb', 'rd', 'cb', 'uyi'],
    ...: 'count' : [3,2,5,8,10,1,2,2,7]
    ...: })

## Apply nlargest(1) to find the max val df, and nlargest(n) gives top n values for df:
In [87]: df.groupby(["sp", "mt"]).apply(lambda x: x.nlargest(1, "count")).reset_index(drop=True)
Out[87]:
   count  mt   sp  val
0      3  S1  MM1    a
1      5  S3  MM1   cb
2      8  S3  MM2   mk
3     10  S4  MM2   bg
4      7  S2  MM4  uyi

2

গ্রুপবাই অবজেক্টে "nlargest" ব্যবহার করার চেষ্টা করুন। নলেজেষ্ট ব্যবহার করার সুবিধাটি হ'ল এটি সারিগুলির সূচকটি ফিরিয়ে দেয় যেখানে "nlargest আইটেমগুলি" নেওয়া হয়েছিল। দ্রষ্টব্য: আমরা আমাদের সূচকের দ্বিতীয় (1) উপাদানটিকে টুকরো টুকরো করি যেহেতু আমাদের সূচকে এই ক্ষেত্রে টিপলস রয়েছে (যেমন (এস 1, 0))।

df = pd.DataFrame({
'sp' : ['MM1', 'MM1', 'MM1', 'MM2', 'MM2', 'MM2', 'MM4', 'MM4','MM4'],
'mt' : ['S1', 'S1', 'S3', 'S3', 'S4', 'S4', 'S2', 'S2', 'S2'],
'val' : ['a', 'n', 'cb', 'mk', 'bg', 'dgb', 'rd', 'cb', 'uyi'],
'count' : [3,2,5,8,10,1,2,2,7]
})

d = df.groupby('mt')['count'].nlargest(1) # pass 1 since we want the max

df.iloc[[i[1] for i in d.index], :] # pass the index of d as list comprehension

এখানে চিত্র বর্ণনা লিখুন


1

আমি অনেক গ্রুপ ক্রিয়াকলাপের জন্য এই কার্যকরী শৈলীটি ব্যবহার করছি:

df = pd.DataFrame({
   'Sp' : ['MM1', 'MM1', 'MM1', 'MM2', 'MM2', 'MM2', 'MM4', 'MM4', 'MM4'],
   'Mt' : ['S1', 'S1', 'S3', 'S3', 'S4', 'S4', 'S2', 'S2', 'S2'],
   'Val' : ['a', 'n', 'cb', 'mk', 'bg', 'dgb', 'rd', 'cb', 'uyi'],
   'Count' : [3,2,5,8,10,1,2,2,7]
})

df.groupby('Mt')\
  .apply(lambda group: group[group.Count == group.Count.max()])\
  .reset_index(drop=True)

    sp  mt  val  count
0  MM1  S1    a      3
1  MM4  S2  uyi      7
2  MM2  S3   mk      8
3  MM2  S4   bg     10

.reset_index(drop=True) গোষ্ঠী-সূচক বাদ দিয়ে আপনাকে আবার মূল সূচকে ফিরে যায়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.