পান্ডাস গ্রুপযুক্ত যোগফল


93

আমি আমার পান্ডাদের ডেটাফ্রেমে একটি সংখ্যক সমষ্টি কলাম যুক্ত করতে চাই যাতে:

name | day       | no
-----|-----------|----
Jack | Monday    | 10
Jack | Tuesday   | 20
Jack | Tuesday   | 10
Jack | Wednesday | 50
Jill | Monday    | 40
Jill | Wednesday | 110

হয়ে:

Jack | Monday     | 10  | 10
Jack | Tuesday    | 30  | 40
Jack | Wednesday  | 50  | 90
Jill | Monday     | 40  | 40
Jill | Wednesday  | 110 | 150

আমি বিভিন্ন কম্বো চেষ্টা করেছিলাম df.groupbyএবং df.agg(lambda x: cumsum(x))কোন লাভ হয়নি।


আপনি কি সত্যই নিশ্চিত যে আপনি সপ্তাহের দিনগুলিতে একত্রিতকরণ চান? এটি সূচকটি হারাবে এবং একাধিক সপ্তাহ থাকলে ক্রমসংখ্যাটিও কম বোঝায়। দিমিত্রি-অ্যান্ড্রিভ এবং @ ভিজেকির উত্তরগুলি পরিবর্তে প্রতিটি নামের জন্য দিনের ক্রম অনুসারে কসমস গণনা করে। যদি একটি তারিখ কলামও থাকে তবে এটি কীভাবে বাড়ানো যেতে পারে তা ভেবে দেখুন, দলবদ্ধকরণ এবং একত্রিত করার আগে এন্ট্রিগুলি বাছাই করা যেতে পারে।
ইলিয়াস হাসেল

উত্তর:


89

এটি করা উচিত, groupby()দুবার প্রয়োজন :

df.groupby(['name', 'day']).sum() \
  .groupby(level=0).cumsum().reset_index()

ব্যাখ্যা:

print(df)
   name        day   no
0  Jack     Monday   10
1  Jack    Tuesday   20
2  Jack    Tuesday   10
3  Jack  Wednesday   50
4  Jill     Monday   40
5  Jill  Wednesday  110

# sum per name/day
print( df.groupby(['name', 'day']).sum() )
                 no
name day           
Jack Monday      10
     Tuesday     30
     Wednesday   50
Jill Monday      40
      Wednesday  110

# cumulative sum per name/day
print( df.groupby(['name', 'day']).sum() \
         .groupby(level=0).cumsum() )
                 no
name day           
Jack Monday      10
     Tuesday     40
     Wednesday   90
Jill Monday      40
     Wednesday  150

প্রথম যোগফলের ফলাফল হিসাবে ডেটাফ্রেম দ্বারা 'name'এবং এর সূচী হয় 'day'। আপনি এটি মুদ্রণ করে দেখতে পারেন

df.groupby(['name', 'day']).sum().index 

ক্রমসংখ্যার যোগফল গণনা করার সময় আপনি 'name'প্রথম সূচক (স্তর 0) এর সাথে মিল রেখে এটি করতে চান ।

সবশেষে, reset_indexনামগুলি পুনরাবৃত্তি করতে ব্যবহার করুন ।

df.groupby(['name', 'day']).sum().groupby(level=0).cumsum().reset_index()

   name        day   no
0  Jack     Monday   10
1  Jack    Tuesday   40
2  Jack  Wednesday   90
3  Jill     Monday   40
4  Jill  Wednesday  150

4
উত্তর করার জন্য ধন্যবাদ. যদিও আমার কিছু প্রশ্ন রয়েছে: ১. 'স্তর = [0]' এর অর্থ কী আপনি দয়া করে ব্যাখ্যা করতে পারেন? ২. এছাড়াও, যেমন আপনি দেখতে পাচ্ছেন, আপনার আগে আপনার ডেটা ফ্রেমে সারি সংখ্যা ছিল এবং একবার ক্রমসংখ্যা যোগ করলে এই সারি সংখ্যাগুলি চলে যায়। তাদের ফিরে পাওয়ার কোনও উপায় আছে কি?
ব্যবহারকারী3694373

4
1), সূচক সংখ্যাটি যেতে হবে, যেমন চামসুমগুলি একাধিক সারি থেকে আসে, যেমন 2 য় সংখ্যা, 40, 10 + 20 + 10, কোন সূচকের মানটি পাওয়া উচিত? 1, 2 বা 3? সুতরাং, আসুন আমরা ব্যবহার করি nameএবং dayহিসাবে রাখি multiIndex, যা আরও ভাল ধারণা দেয় ( সূচি reset_index()পেতে int, পছন্দসই হলে)। 2), এর level=[0]অর্থ groupbyহল MultiIndexকলামের 1 ম স্তরের দ্বারা পরিচালনা করা name
সিটি ঝু

ধন্যবাদ সিটি আমি এটি পরে বুঝতে পেরেছি এবং আমার সমস্যা সমাধানের জন্য পুনরায় সেট_ইন্ডেক্স () চেষ্টা করেছি। বিস্তারিত ব্যাখ্যার জন্য ধন্যবাদ!
ব্যবহারকারী3694373

4
একটি সূক্ষ্ম ত্রুটি রয়েছে: groupby()কীগুলি বাছাইয়ের প্রথম ডিফল্ট, সুতরাং আপনি যদি ইনপুট ডেটাসেটের নীচে একটি জ্যাক-বৃহস্পতিবার সারি যুক্ত করেন তবে আপনি অপ্রত্যাশিত ফলাফল পাবেন। এবং যেহেতু groupby()স্তরের নামের সাথে কাজ করতে পারি আমি df.groupby(['name', 'day'], sort=False).sum().groupby(by='name').cumsum().reset_index()ক্রিপ্টিক কম খুঁজে পাই ।
নিকোলে

আপনি কীভাবে কলামটির নাম পরিবর্তন করবেন?
জোনাথন লাম

47

এটি পান্ডাস 0.16.2 এ কাজ করে

In[23]: print df
        name          day   no
0      Jack       Monday    10
1      Jack      Tuesday    20
2      Jack      Tuesday    10
3      Jack    Wednesday    50
4      Jill       Monday    40
5      Jill    Wednesday   110
In[24]: df['no_cumulative'] = df.groupby(['name'])['no'].apply(lambda x: x.cumsum())
In[25]: print df
        name          day   no  no_cumulative
0      Jack       Monday    10             10
1      Jack      Tuesday    20             30
2      Jack      Tuesday    10             40
3      Jack    Wednesday    50             90
4      Jill       Monday    40             40
5      Jill    Wednesday   110            150

কীভাবে এটি ডিএফ-এ যুক্ত করা যায় তা দেখানো সত্যিই সহায়ক। আমি ট্রান্সফর্মটি ব্যবহার করার চেষ্টা করেছি, তবে এটি cumsum () দিয়ে খুব সুন্দরভাবে খেলেনি।
zerovector

4
নোট করুন যে এই উত্তরটি ( @ বিজয়কির সহজ সমাধানের সমতুল্য বলে মনে হচ্ছে ) দ্বারা সংযোজক যোগফল গণনা করার আগে nameএবং সমষ্টিগত হয় না (দ্রষ্টব্য: জ্যাক + মঙ্গলবারে ফলাফলের জন্য 2 টি সারি রয়েছে)। এটিই এটি সিটি ঝুয়ের উত্তরের চেয়ে সহজ করে তুলেছেdayname
নিকোলে

39

@ দিমিত্রি এর উত্তরে পরিবর্তন। এটি সহজ এবং পান্ডাস 0.19.0 এ কাজ করে:

print(df) 

 name        day   no
0  Jack     Monday   10
1  Jack    Tuesday   20
2  Jack    Tuesday   10
3  Jack  Wednesday   50
4  Jill     Monday   40
5  Jill  Wednesday  110

df['no_csum'] = df.groupby(['name'])['no'].cumsum()

print(df)
   name        day   no  no_csum
0  Jack     Monday   10       10
1  Jack    Tuesday   20       30
2  Jack    Tuesday   10       40
3  Jack  Wednesday   50       90
4  Jill     Monday   40       40
5  Jill  Wednesday  110      150

4
প্রশ্নটিতে অনুরোধ অনুসারে আপনার যদি দ্বি-পদক্ষেপের সমষ্টি প্রয়োজন না হয় তবে এটি সর্বাধিক সহজ সমাধান বলে মনে হচ্ছে ।
নিকোলে

আমি কেবলমাত্র বিশেষ অংশটি পছন্দ করি না তা হ'ল এটি আমার ইনটি টাইপটিকে একটি ফ্লোটে রূপান্তরিত করে।
ক্রিস ফার

এটি গ্রুপ অংশে cumsum জন্য গৃহীত উত্তর হওয়া উচিত। @ ক্রিসফায়ার আমার কাছে পান্ডাসের ১.৩.৩ হিসাবে ভাসতে রূপান্তরিত হবে বলে মনে হয় না।
লুই ইয়াং

8

আপনার ব্যবহার করা উচিত

df['cum_no'] = df.no.cumsum()

http://pandas.pydata.org/pandas-docs/version/0.19.2/generated/pandas.DataFrame.cumsum.html

এটি করার আরেকটি উপায়

import pandas as pd
df = pd.DataFrame({'C1' : ['a','a','a','b','b'],
           'C2' : [1,2,3,4,5]})
df['cumsum'] = df.groupby(by=['C1'])['C2'].transform(lambda x: x.cumsum())
df

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


4
এটি প্রতিটি গোষ্ঠীর জন্য পৃথক পৃথক অঙ্কের পরিবর্তে বিশ্বব্যাপী চলমান মোট গণনা করে। সুতরাং জিল-সোমবারের জন্য 130 এর মান নির্ধারিত হয় ( 90সমস্ত জ্যাকের মানগুলির সমষ্টি হিসাবে, + 40, জিল-সোমবারের মান)।
নিকোলে

@ নিকোলে মাত্র একটি উত্তর যুক্ত করেছেন এটি কাজ করে কিনা আমাকে জানতে দিন

আমি নিশ্চিত নই যে এটি আমার উদাহরণ সারি 3 অনুসারে গ্লোবাল চলমান মোট গণনা করে কিনা 3 এর 4
টির

আমি এখানে ল্যান্ডডা x: x.cumsum () ব্যবহার করব না কেন, পান্ডাস.সরিজ.সামস () এর পরিবর্তে?
জিনহুয়া ওয়াং

7

পরিবর্তে df.groupby(by=['name','day']).sum().groupby(level=[0]).cumsum() (উপরে দেখুন) আপনি এও করতে পারেনdf.set_index(['name', 'day']).groupby(level=0, as_index=False).cumsum()

  • df.groupby(by=['name','day']).sum() উভয় কলামটি আসলে একটি মাল্টিআইডেক্সে সরাচ্ছে
  • as_index=False এর অর্থ আপনার পরে পুনরায় সেট_ইন্ডেক্স কল করার দরকার নেই

এটি পোস্ট করার জন্য ধন্যবাদ, এটি আমাকে এখানে কী হচ্ছে তা বুঝতে সহায়তা করেছে! লক্ষ্য করুন groupby().sum()না শুধু MultiIndex উভয় কলাম চলন্ত - এটি জ্যাক + + মঙ্গলবার দুটি মান আপ। আর as_index=Falseএই ক্ষেত্রে কোনো প্রভাব যেহেতু সূচক ইতিমধ্যেই আগে ছিল বলে মনে হচ্ছে না groupby। এবং যেহেতু groupby().cumsum()ডেটা ফ্রেমের কলামগুলি থেকে নাম / দিনকে সংকুচিত করে, তাই আপনাকে ফলস্বরূপ সংখ্যাসূচক কলামটি মূল ডেটা ফ্রেমে যুক্ত করতে হবে (যেমন বিজয়কি এবং দিমিত্রি প্রস্তাবিত), অথবা নাম / দিনকে সূচিতে স্থানান্তর করতে হবে এবং তারপরে পুনরায় সেট করুন_আইডেক্স।
নিকোলে

0

ডেটা.সিএসভি:

name,day,no
Jack,Monday,10
Jack,Tuesday,20
Jack,Tuesday,10
Jack,Wednesday,50
Jill,Monday,40
Jill,Wednesday,110

কোড:

import numpy as np
import pandas as pd

df = pd.read_csv('data.csv')
print(df)
df = df.groupby(['name', 'day'])['no'].sum().reset_index()
print(df)
df['cumsum'] = df.groupby(['name'])['no'].apply(lambda x: x.cumsum())
print(df)

আউটপুট:

   name        day   no
0  Jack     Monday   10
1  Jack    Tuesday   20
2  Jack    Tuesday   10
3  Jack  Wednesday   50
4  Jill     Monday   40
5  Jill  Wednesday  110
   name        day   no
0  Jack     Monday   10
1  Jack    Tuesday   30
2  Jack  Wednesday   50
3  Jill     Monday   40
4  Jill  Wednesday  110
   name        day   no  cumsum
0  Jack     Monday   10      10
1  Jack    Tuesday   30      40
2  Jack  Wednesday   50      90
3  Jill     Monday   40      40
4  Jill  Wednesday  110     150
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.