kidchae
kidchae

Reputation: 31

How do I create a list in a separate Dataframe column from specific values from within a list of dictionaries?

I have a Dataframe called 'new_api_df' with a column called new_api_df['Categories'] that contains a list of dictionaries:

[{'CallId': 22143866, 'BucketId': 1953, 'SectionId': 1256, 'BucketFullName': 'Categories.Filters.No Sale Made', 'Weight': 1.0}
, {'CallId': 22143866, 'BucketId': 2016, 'SectionId': 1255, 'BucketFullName': 'Categories.Imported.Objections', 'Weight': 3.0}
, {'CallId': 22143866, 'BucketId': 2017, 'SectionId': 1255, 'BucketFullName': 'Categories.Imported.Touting Benefits', 'Weight': 1.0}
]

I want to take every 'BucketFullName' and place those values into a list in a separate column new_api_df['category_list'] as such:

['Categories.Filters.No Sale Made', 'Categories.Imported.Objections', Categories.Imported.Touting Benefits']

I've tried using list comprehension, as such:

new_api_df['category_list'] =[item['BucketFullName'] for dictionary in new_api_df['Categories'] for item in dictionary]

but get the error: ValueError: Length of values does not match length of index

I've also tried apply and list comprehension: new_api_df['category_list'] = new_api_df['Categories'].apply([item['BucketFullName'] for dictionary in new_api_df['Categories'] for item in dictionary])

but I get the following error: AttributeError: 'Categories.Filters.No Sale Made' is not a valid function for 'Series' object

I've also tried: new_api_df['category_list'] = df['Categories'].apply(lambda x: x['BucketFullName'])

but get the error: TypeError: list indices must be integers or slices, not str

new_api_df slices:

new_api_df.loc[0]:

Contact            {'Id': 22143866, 'Type': 'Call', 'WavPath': '\...
RecordInfo         {'Id': 22143866, 'RowNumber': 1, 'TotalRowCoun...
Measures           {'ID': 22143866, 'TotalHoldCount': 0, 'Agitati...
Others             {'ConfidenceAverage': 69, 'SequenceID': None, ...
Sections           [{'CallId': 22143866, 'SectionId': 1041, 'Sect...
Categories         [{'CallId': 22143866, 'BucketId': 1953, 'Secti...
Scores             [{'CallId': 22143866, 'ScoreId': 399, 'ScoreNa...
ScoreComponents    [{'CallId': 22143866, 'ScoreComponentId': 4497...```

Upvotes: 1

Views: 81

Answers (1)

ansev
ansev

Reputation: 30930

I think you want

df=pd.DataFrame({'Categories':[{'CallId': 22143866, 'BucketId': 1953, 'SectionId': 1256, 'BucketFullName': 'Categories.Filters.No Sale Made', 'Weight': 1.0}
, {'CallId': 22143866, 'BucketId': 2016, 'SectionId': 1255, 'BucketFullName': 'Categories.Imported.Objections', 'Weight': 3.0}
, {'CallId': 22143866, 'BucketId': 2017, 'SectionId': 1255, 'BucketFullName': 'Categories.Imported.Touting Benefits', 'Weight': 1.0}
]})

df['category_list']=df['Categories'].apply(lambda x: x[0]['BucketFullName'])
print(df)

#                                          Categories  \
#0  {'CallId': 22143866, 'BucketId': 1953, 'Sectio...   
#1  {'CallId': 22143866, 'BucketId': 2016, 'Sectio...   
#2  {'CallId': 22143866, 'BucketId': 2017, 'Sectio...   
#
#                          category_list  
#0       Categories.Filters.No Sale Made  
#1        Categories.Imported.Objections  
#2  Categories.Imported.Touting Benefits  

UPDATE

Note that this creates a list for each cell.

df['category_list']=df['Categories'].apply(lambda x: [m_dict['BucketFullName'] for m_dict in x])

then you can use DataFrame.explode

df = df.explode('category_list')
#(df['Categories'].apply(lambda x: [m_dict['BucketFullName'] for m_dict in x])                                                             
#                  .explode()) #check the explode serie

Upvotes: 1

Related Questions