3

I have a pandas dataframe:

pd.DataFrame({'id': [1, 1, 2, 2, 3, 3],
         'payment_count': 1, 2, 1, 2, 1, 2,
         'payment_date': ['2/2/2020', '4/6/2020', '3/20/2020', '3/29/2020', '5/1/2020', '5/30/2020']})

I want to take max('payment_count') by each 'id' and create a new column with the associated 'payment_date'. Desired output:

pd.DataFrame({'id': [1, 2, 3],
         'payment_date_1': ['2/2/2020', '3/20/2020', '5/1/2020'],
         'payment_date_2': ['4/6/2020', '3/29/2020', '5/30/2020']})

3 Answers3

3

You can try with pivot, add_prefix, rename_axis and reset_index

df.pivot(index='id',columns='payment_count',values='payment_date_')\
   .rename_axis(None, axis = 1)\
   .add_prefix('payment_date')\
   .reset_index() 

Output:

   id payment_date_1 payment_date_2
0   1      2/2/2020      4/6/2020
1   2     3/20/2020     3/29/2020
2   3      5/1/2020     5/30/2020
MrNobody33
  • 6,413
  • 7
  • 19
1

Another way using groupby.

df['paydate'] = df.groupby('id')['payment_date'].cumcount()+1
df['paydate'] = 'payment_date' + df['paydate'].astype(str)
df = df.set_index(['paydate','id'])['payment_date']
df = df.unstack(0).rename_axis(None)
rhug123
  • 7,893
  • 1
  • 9
  • 24
  • 1
    Awesome, this actually was the best option for me, as my real data had up to 50 'payment_count', so the pivot created 50 new columns which I didn't need. – Michael Mathews Jr. Jul 30 '20 at 20:12
0

Ugly but it does what you asked. pivot sounds better though.

groups = df.groupby('id')
args = {group[0]:group[1].payment_count.argsort() for group in groups}

records = []
for k,v in args.items():
    payments = {f'payment_{i}':date
                for i,date in enumerate(df.payment_date[v])}
    payments['id'] = k
    records.append(payments)

_df = pd.DataFrame(records)
Nathan Chappell
  • 2,099
  • 18
  • 21