Вы можете сделать это с помощью:
ideal_df = df.set_index(["AnimalClassId"])["Animal"]\
.apply(pd.Series)\
.stack()\
.reset_index(level=1, drop=True)\
.reset_index()
ideal_df.columns = ["AnimalClassId", "Animal"]
(обратите внимание, что вы можете поместить это все в одну строку или разбить на отдельные строки)
Пример:
input (ваш пример):
df = pd.DataFrame({
"Animal": [
[{"animalid":1,"color":"red","name":"cat"}, {"animalid":2,"color":"blue","name":"cat2"}],
[{"animalid":3,"color":"pink","name":"pig"}]
],
"AnimalClassId": [1, 2]
})
print(df)
Animal AnimalClassId
0 [{'animalid': 1, 'color': 'red', 'name': 'cat'... 1
1 [{'animalid': 3, 'color': 'pink', 'name': 'pig'}] 2
output:
print(ideal_df)
AnimalClassId Animal
0 1 {'animalid': 1, 'color': 'red', 'name': 'cat'}
1 1 {'animalid': 2, 'color': 'blue', 'name': 'cat2'}
2 2 {'animalid': 3, 'color': 'pink', 'name': 'pig'}
Если у вас больше столбцов, чем просто "AnimalClassId", вам нужно будет включить их в список, переданный set_index
, и увеличьте значение параметра level
, переданное до reset_index
, на 1 для каждого дополнительного столбца.Например, если бы у вас был столбец «AnimalHabitat», то вам понадобились бы set_index(["AnimalClassId", "AnimalHabitat"])
и reset_index(level=2, drop=True)
.
Это все равно придется зацикливать ваши данные за кулисами.Поскольку данные в столбце «Животное» не являются единообразными (списки различной длины), я сомневаюсь, что есть способ развернуть каждый элемент в векторизованном виде, но это поможет.