এখানে শীর্ষ দুটি উত্তর প্রস্তাব:
df.groupby(cols).agg(lambda x:x.value_counts().index[0])
বা, পছন্দসই
df.groupby(cols).agg(pd.Series.mode)
তবে এখানে উভয়ই সাধারণ প্রান্তের ক্ষেত্রে ব্যর্থ হয়েছে:
df = pd.DataFrame({
'client_id':['A', 'A', 'A', 'A', 'B', 'B', 'B', 'C'],
'date':['2019-01-01', '2019-01-01', '2019-01-01', '2019-01-01', '2019-01-01', '2019-01-01', '2019-01-01', '2019-01-01'],
'location':['NY', 'NY', 'LA', 'LA', 'DC', 'DC', 'LA', np.NaN]
})
প্রথম:
df.groupby(['client_id', 'date']).agg(lambda x:x.value_counts().index[0])
ফলন IndexError
(কারণ খালি সিরিজ দলবদ্ধভাবে ফিরে এসেছে C
)। দ্বিতীয়:
df.groupby(['client_id', 'date']).agg(pd.Series.mode)
প্রত্যাবর্তন হয় ValueError: Function does not reduce
, যেহেতু প্রথম গোষ্ঠী দুটিটির তালিকা দেয় (যেহেতু দুটি মোড রয়েছে)। ( এখানে দলিল হিসাবে , প্রথম গোষ্ঠী একটি একক মোড ফিরিয়ে দিলে এটি কার্যকর হবে!)
এই মামলার দুটি সম্ভাব্য সমাধান হ'ল:
import scipy
x.groupby(['client_id', 'date']).agg(lambda x: scipy.stats.mode(x)[0])
এবং সমাধানটি আমাকে এখানে মন্তব্যগুলিতে সিএস 95 দ্বারা প্রদত্ত :
def foo(x):
m = pd.Series.mode(x);
return m.values[0] if not m.empty else np.nan
df.groupby(['client_id', 'date']).agg(foo)
তবে এগুলি সমস্ত ধীর এবং বড় ডেটাসেটের জন্য উপযুক্ত নয়। একটি সমাধান যা আমি ব্যবহার করে শেষ করেছি) ক) এই কেসগুলি মোকাবেলা করতে পারে এবং খ) অনেক বেশি দ্রুত, এটি আবদু 33 এর উত্তরের হালকা পরিবর্তিত সংস্করণ (যা আরও বেশি হওয়া উচিত):
def get_mode_per_column(dataframe, group_cols, col):
return (dataframe.fillna(-1)
.groupby(group_cols + [col])
.size()
.to_frame('count')
.reset_index()
.sort_values('count', ascending=False)
.drop_duplicates(subset=group_cols)
.drop(columns=['count'])
.sort_values(group_cols)
.replace(-1, np.NaN))
group_cols = ['client_id', 'date']
non_grp_cols = list(set(df).difference(group_cols))
output_df = get_mode_per_column(df, group_cols, non_grp_cols[0]).set_index(group_cols)
for col in non_grp_cols[1:]:
output_df[col] = get_mode_per_column(df, group_cols, col)[col].values
মূলত, পদ্ধতিটি একবারে একটি কর্নে কাজ করে এবং একটি ডিএফ আউটপুট দেয়, তার পরিবর্তে concat
, যা নিবিড় হয়, আপনি প্রথমে একটি ডিএফ হিসাবে বিবেচনা করেন এবং তারপরে পুনরাবৃত্তভাবে values.flatten()
ডিএফ-এ একটি কলাম হিসাবে আউটপুট অ্যারে ( ) যুক্ত করুন ।