পান্ডারা প্রতিটি গ্রুপের মধ্যে শীর্ষস্থানীয় এন রেকর্ড পান


162

ধরুন আমার কাছে এই জাতীয় প্যানডাস ডেটা ফ্রেম রয়েছে:

>>> df = pd.DataFrame({'id':[1,1,1,2,2,2,2,3,4],'value':[1,2,3,1,2,3,4,1,1]})
>>> df
   id  value
0   1      1
1   1      2
2   1      3
3   2      1
4   2      2
5   2      3
6   2      4
7   3      1
8   4      1

আমি প্রতিটি আইডির জন্য শীর্ষ 2 রেকর্ড সহ একটি নতুন ডাটাফ্রেম পেতে চাই:

   id  value
0   1      1
1   1      2
3   2      1
4   2      2
7   3      1
8   4      1

আমি গ্রুপের পরে গ্রুপ অনুসারে রেকর্ডিংয়ের সাথে এটি করতে পারি:

>>> dfN = df.groupby('id').apply(lambda x:x['value'].reset_index()).reset_index()
>>> dfN
   id  level_1  index  value
0   1        0      0      1
1   1        1      1      2
2   1        2      2      3
3   2        0      3      1
4   2        1      4      2
5   2        2      5      3
6   2        3      6      4
7   3        0      7      1
8   4        0      8      1
>>> dfN[dfN['level_1'] <= 1][['id', 'value']]
   id  value
0   1      1
1   1      2
3   2      1
4   2      2
7   3      1
8   4      1

তবে এটি করার জন্য আরও কার্যকর / মার্জিত পদ্ধতির কী আছে? এবং প্রতিটি গ্রুপের মধ্যে নম্বর রেকর্ডে আরও মার্জিত পন্থা রয়েছে (যেমন এসকিউএল উইন্ডো ফাংশন রো_নম্বার () )।



1
"শীর্ষ-এন" এর অর্থ "এন শীর্ষস্থানীয় / প্রথম / প্রধান সারিগুলি" নয়, যেমন আপনি খুঁজছেন! এর অর্থ "বৃহত্তম মান সহ এন সারি"।
স্মি

উত্তর:


181

তুমি কি চেষ্টা করেছিলে df.groupby('id').head(2)

আউটপুট উত্পন্ন:

>>> df.groupby('id').head(2)
       id  value
id             
1  0   1      1
   1   1      2 
2  3   2      1
   4   2      2
3  7   3      1
4  8   4      1

(মনে রাখবেন যে আপনার আগে আপনার ডেটার উপর নির্ভর করে অর্ডার / সাজানোর দরকার হতে পারে)

সম্পাদনা: প্রশ্নকারী দ্বারা উল্লিখিত হিসাবে, df.groupby('id').head(2).reset_index(drop=True)মাল্টিইন্ডেক্স অপসারণ এবং ফলাফল সমতল করতে ব্যবহার করুন ।

>>> df.groupby('id').head(2).reset_index(drop=True)
    id  value
0   1      1
1   1      2
2   2      1
3   2      2
4   3      1
5   4      1

1
হ্যাঁ, আমি মনে করি এটিই। এটি কোনওভাবে উপেক্ষা করে। আপনি গ্রুপ মধ্যে রেকর্ড নম্বর ভাল উপায় জানেন?
রোমান পেকার

4
আমার আউটপুট পেতে, আমি আরও যুক্ত করেছি.reset_index(drop=True)
রোমান পেকার

1
github.com/pydata/pandas/pull/5510 সবেমাত্র একত্রিত হয়েছে; ০.১৩ এ হবে, cumcountএকে একে একে একে নতুনভাবে চিহ্নিত করার পদ্ধতিটি (প্রতিটি গ্রুপের রেকর্ড সংখ্যা)
জেফ

1
@ জেফ সুসংবাদ। আমি আশা করি পান্ডসে অবদান রাখার জন্য আমার আরও সময় ছিল :(
রোমান পেকার

3
@ ডারভাককে তার উত্তর আরও সম্পূর্ণ করতে আপনি যদি 2 টির চেয়ে কম ছোট মান চান idতবে তা করুন df.sort_values(['id', 'value'], axis=0).groupby('id').head(2)। অন্য একটি উদাহরণ, প্রতি বৃহত্তম মান idদ্বারা দেওয়া হয় df.sort_values(['id', 'value'], axis=0).groupby('id').tail(1)
Elmex80s

131

0.14.1 সাল থেকে , আপনি এখন nlargestএবং nsmallestএকটি groupbyঅবজেক্টে করতে পারেন :

In [23]: df.groupby('id')['value'].nlargest(2)
Out[23]: 
id   
1   2    3
    1    2
2   6    4
    5    3
3   7    1
4   8    1
dtype: int64

সেখানে সামান্য weirdness যে আপনি সেখানে মূল সূচক পাশাপাশি পেতে, কিন্তু এই কি আপনার আসল সূচক উপর নির্ভর করে সত্যিই দরকারী হতে পারে ছিল

আপনি যদি এতে আগ্রহী না হন তবে আপনি .reset_index(level=1, drop=True)এটি পুরোপুরি পরিত্রাণ পেতে পারেন।

(দ্রষ্টব্য: ০.০ From.১ থেকে আপনি ডেটা ফ্রেমগ্রুপবিতেও এটি করতে সক্ষম হবেন তবে আপাতত এটি কেবল Seriesএবং এর সাথে কাজ করে SeriesGroupBy))


পাওয়ার উপায় আছে unique_limit(n)? আমি চাই প্রথম এন অনন্য মান চান? আমি যদি nlargestএটির জন্য জিজ্ঞাসা করি তবে পুরো
ডিএফটি

2
আপনি গ্রুপবাইতে সমষ্টি করার সময় এটি ক্ষেত্রে কাজ করে না? উদাহরণস্বরূপ, df.groupby([pd.Grouper(freq='M'), 'A'])['B'].count().nlargest(5, 'B') এটি কেবলমাত্র প্রতিটি গ্রুপের দ্বারা নয়, পুরো সিরিজে সামগ্রিক শীর্ষ 5 প্রদান করবে
Geominded

এটি এখন DataFrameGroupBys এর পক্ষেও সম্ভব হয়েছে এমন বিবৃতিটি মিথ্যা বলে মনে হচ্ছে, লিঙ্কযুক্ত পুল অনুরোধটি কেবল nlargestসহজ DataFrameসরলগুলিতে যুক্ত হবে appears কোনটি দুর্ভাগ্যজনক, কারণ আপনি যদি একাধিক কলাম নির্বাচন করতে চান তবে কী হবে?
আউলেঞ্জ

7

কখনও কখনও পুরো ডেটা বাছাই করা খুব সময় সাশ্রয়ী। আমরা প্রথমে গোষ্ঠীভুক্ত করে প্রতিটি গ্রুপের জন্য টপকে কাজ করতে পারি:

g = df.groupby(['id']).apply(lambda x: x.nlargest(topk,['value'])).reset_index(drop=True)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.