23

I have the following data:

Invoice NoStockCode Description                         Quantity    CustomerID  Country
536365  85123A      WHITE HANGING HEART T-LIGHT HOLDER  6           17850       United Kingdom
536365  71053       WHITE METAL LANTERN                 6           17850       United Kingdom
536365  84406B      CREAM CUPID HEARTS COAT HANGER      8           17850       United Kingdom

I am trying to do a groupby so i have the following operation:

df.groupby(['InvoiceNo','CustomerID','Country'])['NoStockCode','Description','Quantity'].apply(list)

I want to get the output

|Invoice |CustomerID |Country        |NoStockCode              |Description                                                                                 |Quantity       
|536365| |17850      |United Kingdom |85123A, 71053, 84406B    |WHITE HANGING HEART T-LIGHT HOLDER, WHITE METAL LANTERN, CREAM CUPID HEARTS COAT HANGER     |6, 6, 8            

Instead I get:

|Invoice |CustomerID |Country        |0         
|536365| |17850      |United Kingdom |['NoStockCode','Description','Quantity']

I have tried agg and other methods, but I haven't been able to get all of the columns to join as a list. I don't need to use the list function, but in the end I want the different columns to be lists.

4 Answers 4

37

I can't reproduce your code right now, but I think that:

print (df.groupby(['InvoiceNo','CustomerID','Country'], 
                  as_index=False)['NoStockCode','Description','Quantity']
          .agg(lambda x: list(x)))

would give you the expected output

Sign up to request clarification or add additional context in comments.

3 Comments

How can I use ['NoStockCode','Description','Quantity'] as a variable? something like: df.groupby(list_1, as_index=False)list_2.agg(lambda x: list(x))
can't try but does df.groupby(list_1, as_index=False)[list_2].agg(lambda x: list(x)) works?
No, I add to create a dict with what action to do on each columns and use dataframe.groupby(self.get_index_keys()).agg(actions).reset_index() action could be lambda x: json.dumps(list(x), default=str) if x.item() else None or first
6

IIUC

df.groupby(['Invoice','CustomerID'],as_index=False)['Description','NoStockCode'].agg(','.join)
Out[47]: 
   Invoice  CustomerID                                        Description  \
0   536365       17850  WHITEHANGINGHEARTT-LIGHTHOLDER,WHITEMETALANTER...   
           NoStockCode  
0  85123A,71053,84406B  

Comments

1

Try using a variation of the following:

df.groupby('company').product.agg([('count', 'count'), ('NoStockCode', ', '.join), ('Descrption', ', '.join), ('Quantity', ', '.join)])

Comments

1

You could use pd.pivot_table with aggfunc=list:

import pandas as pd
df = pd.DataFrame({'Country': ['United Kingdom', 'United Kingdom', 'United Kingdom'],
                   'CustomerID': [17850, 17850, 17850],
                   'Description': ['WHITE HANGING HEART T-LIGHT HOLDER',
                                   'WHITE METAL LANTERN',
                                   'CREAM CUPID HEARTS COAT HANGER'],
                   'Invoice': [536365, 536365, 536365],
                   'NoStockCode': ['85123A', '71053', '84406B'],
                   'Quantity': [6, 6, 8]})

result = pd.pivot_table(df, index=['Invoice','CustomerID','Country'], 
                        values=['NoStockCode','Description','Quantity'], 
                        aggfunc=lambda x: ', '.join(map(str, x)))
print(result)

yields

                                                                         Description            NoStockCode Quantity
Invoice CustomerID Country                                                                                          
536365  17850      United Kingdom  WHITE HANGING HEART T-LIGHT HOLDER, WHITE META...  85123A, 71053, 84406B  6, 6, 8

Note that if Quantity are ints, you will need to convert them to strs before calling ', '.join. That is why map(str, x) was used above.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.