Pandas AssertionError при применении функции, которая возвращает кортеж, содержащий список - PullRequest
1 голос
/ 21 июня 2020

Я применяю функцию к Pandas DataFrame и возвращаю tuple для преобразования в несколько DataFrame столбцов с использованием zip(* ).

Возвращаемый tuple, содержит a list, содержащий один или несколько tuples.

В случаях, когда хотя бы один из вложенных lists содержит количество tuples, отличное от остального lists, все работает нормально.

В редких случаях, когда функция возвращает все вложенные lists с равными tuple счетчиками внутри, возникает AssertionError: Shape of new values must be compatible with manager shape.

Я подозреваю Pandas видит согласованные вложенные list длины и пытается распаковать list(tuples) в отдельные столбцы.

Как я могу заставить Pandas всегда хранить возвращенные list как есть, независимо от условий выше?


(Python 3.7.4, Pandas 1.0.3)

Код, который работает:

import pandas as pd
import numpy as np

def simple_function(type_count):
    calculated_value1 = np.random.randint(5)
    calculated_value2 = np.random.randint(5)
    types_list = [tuple((x, calculated_value2)) for x in range(0, type_count)]
    return calculated_value1, types_list
    
df = pd.DataFrame([{'name': 'Joe', 'types': 1},
                   {'name': 'Beth', 'types': 1},
                   {'name': 'John', 'types': 1},
                   {'name': 'Jill', 'types': 2},
                   ], columns=['name', 'types'])

df['calculated_result'], df['types_list'] = zip(*df['types'].apply(simple_function))

Код, который вызывает AssertionError: Shape of new values must be compatible with manager shape:

import pandas as pd
import numpy as np

def simple_function(type_count):
    calculated_value1 = np.random.randint(5)
    calculated_value2 = np.random.randint(5)
    types_list = [tuple((x, calculated_value2)) for x in range(0, type_count)]
    return calculated_value1, types_list
    
df = pd.DataFrame([{'name': 'Joe', 'types': 1},
                   {'name': 'Beth', 'types': 1},
                   {'name': 'John', 'types': 1},
                   {'name': 'Jill', 'types': 1},
                   ], columns=['name', 'types'])

df['calculated_result'], df['types_list'] = zip(*df['types'].apply(simple_function))

1 Ответ

0 голосов
/ 21 июня 2020

Создав DataFrame из списка в вашем результате:

df[['calculated_result','types_list']] = pd.DataFrame(df['types'].apply(simple_function).tolist())

Вы можете получить аналогичный результат с массивом

df['calculated_result'], df['types_list'] = np.array(df['types'].apply(simple_function).tolist()).T
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...