#python #pandas #dataframe #optimization #pivot-table
#python #pandas #фрейм данных #оптимизация #сводная таблица
Вопрос:
У меня есть длинный фрейм данных для сглаживания. Фрейм данных выглядит следующим образом. Я хочу сгладить эту таблицу, использовать referenceDate
companyId
в качестве индекса, столбцы должны иметь два слоя, первый data_item
— это, а второй будет N
. Я знаю, что pd.pivot решит проблему.
--------------- ----------- ----------- --- -------
| referenceDate | CompanyId | data_item | N | value |
--------------- ----------- ----------- --- -------
| 2020-01-31 | 1 | A | 1 | 0.1 |
| 2020-01-31 | 2 | A | 2 | 0.2 |
| 2020-01-31 | 3 | A | 3 | 0.3 |
--------------- ----------- ----------- --- -------
Однако,
df = pd.pivot(df, values='value', index=['referenceDate', 'companyId'], columns=['data_item', 'N'])
всегда выдает ошибку ValueError
Traceback (most recent call last):
File "C:Users\PycharmProjectsvenvs\libsite-packagesIPythoncoreinteractiveshell.py", line 3343, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-56-3738f20d42ed>", line 1, in <module>
df = pd.pivot(df, values='value', index=['referenceDate', 'companyId'], columns=['data_item', 'N'])
File "C:Users\PycharmProjectsvenvs\libsite-packagespandascorereshapepivot.py", line 429, in pivot
indexed = data._constructor_sliced(data[values].values, index=index)
File "C:Users\PycharmProjectsvenvs\libsite-packagespandascoreseries.py", line 302, in __init__
"index implies {ind}".format(val=len(data), ind=len(index))
ValueError: Length of passed values is 239689, index implies 2
pd.pivot_table
работает хорошо, но в этом случае мне не нужна агрегация, и я также обеспокоен производительностью, когда фрейм данных имеет большой размер (в миллиардах строк). На самом деле у меня здесь ошибка памяти, в нем говорится, что не удается выделить 1.xxGB для массива numpy, когда я выполнил это:
df = pd.pivot_table(df, values='value', index=['referenceDate', 'companyId'],
columns=['data_item', 'N'], aggfunc='first')
Мне было интересно, почему pd.pivot
сбой здесь и рядом pd.pivot
и pd.pivot_table
, если есть оптимальное решение (требующее наименьшего объема памяти) для моей проблемы?
Комментарии:
1. На какой версии pandas вы работаете? Вы можете проверить с помощью
pd.__version__
2. @DavidErickson 0.25.3, это было из этого проекта requirements.txt . Будет ли это проблемой?
3. смотрите мой ответ. Я почти уверен, что это связано с наличием более старой версии pandas, в которой
pivot
были ошибки.4. пожалуйста, примите один из ответов в качестве решения, нажав на галочку рядом с моим ответом. Спасибо!
Ответ №1:
Попробуйте перейти на более новую версию pandas, если вы можете временно или постоянно, поскольку pivot
в более ранних версиях pandas есть ошибки.
Например, вы можете сделать это: pip install pandas==1.1.3
обновить до определенной версии, где они исправлены pivot
.
pip install pandas==1.1.3
# then restart the kernel
import pandas as pd
# df = ....
df = pd.pivot(df, values='value', index=['referenceDate', 'CompanyId'], columns=['data_item', 'N'])
df
Out[1]:
data_item A
N 1 2 3
referenceDate CompanyId
2020-01-31 1 0.1 NaN NaN
2 NaN 0.2 NaN
3 NaN NaN 0.3
Затем вы всегда можете вернуться к pip install pandas==0.25.3
. Вы можете сделать все это из своего блокнота jupyter. Обязательно перезапускайте ядро при каждом переключении версий.
Моя текущая версия pandas 1.0.1
, поэтому я также получаю ту же ошибку!
pip install pandas==1.0.1
#restart kernel
import pandas as pd
#df = ...
df = pd.pivot(df, values='value', index=['referenceDate', 'CompanyId'], columns=['data_item', 'N'])
df
Ошибка:
ValueError Traceback (most recent call last)
<ipython-input-2-11248dbe0eba> in <module>
1 df = d.copy()
----> 2 df = pd.pivot(df, values='value', index=['referenceDate', 'CompanyId'], columns=['data_item', 'N'])
3 df
C:Usersdavid.ericksonAnaconda3libsite-packagespandascorereshapepivot.py in pivot(data, index, columns, values)
445 )
446 else:
--> 447 indexed = data._constructor_sliced(data[values].values, index=index)
448 return indexed.unstack(columns)
449
C:Usersdavid.ericksonAnaconda3libsite-packagespandascoreseries.py in __init__(self, data, index, dtype, name, copy, fastpath)
290 if len(index) != len(data):
291 raise ValueError(
--> 292 f"Length of passed values is {len(data)}, "
293 f"index implies {len(index)}."
294 )
ValueError: Length of passed values is 3, index implies 2.