Ошибка: UFuncTypeError: ufunc 'add' did not contain a loop with signature matching types (dtype(' dtype('

На выходе надо получить интервалы разбитые на группы вот в таком виде:

Interval
A1    A1-A2; A1-A1; A1-A3; A1-A1
A2    A2-A3; A2-A2; A2-A1; A2-A2
A3    A3-A2; A3-A2; A3-A1; A3-A3
A4                  A4-A3; A4-A4
A6                         A6-A4
A7                         A7-A8
A8           A8-A6; A8-A9; A8-A8
A9                  A9-A8; A9-A7
Name: x, dtype: object

Но получаю такую ошибку:

Traceback (most recent call last):
  File "/home/kirill/pythonProject/main.py", line 21, in <module>
    df.loc[1:, "x"] = df.loc[1:, "Interval"].cat.codes + "-" + df["Interval"].shift().loc[1:]
  File "/home/kirill/pythonProject/venv/lib/python3.8/site-packages/pandas/core/ops/common.py", line 65, in new_method
    return method(self, other)
  File "/home/kirill/pythonProject/venv/lib/python3.8/site-packages/pandas/core/ops/__init__.py", line 343, in wrapper
    result = arithmetic_op(lvalues, rvalues, op)
  File "/home/kirill/pythonProject/venv/lib/python3.8/site-packages/pandas/core/ops/array_ops.py", line 190, in arithmetic_op
    res_values = na_arithmetic_op(lvalues, rvalues, op)
  File "/home/kirill/pythonProject/venv/lib/python3.8/site-packages/pandas/core/ops/array_ops.py", line 150, in na_arithmetic_op
    result = masked_arith_op(left, right, op)
  File "/home/kirill/pythonProject/venv/lib/python3.8/site-packages/pandas/core/ops/array_ops.py", line 112, in masked_arith_op
    result[mask] = op(xrav[mask], y)
numpy.core._exceptions.UFuncTypeError: ufunc 'add' did not contain a loop with signature matching types (dtype('<U4'), dtype('<U4')) -> dtype('<U4')

Process finished with exit code 1

Вот мой код реализации:

import pandas as pd
import numpy as np

# Импортируй

excel_file = pd.ExcelFile('example.xlsx')
require_cols = [1]
df = pd.read_excel('example.xlsx', usecols=require_cols)
df_min_max = df.aggregate(['min', 'max'])
my_list = df["Data"].tolist()

# Меняем кол-во интервалов
bins = 9

# Сопоставляем данные с интервалами
interval = pd.cut(np.array(my_list), bins)
iv = df["Interval"] = pd.cut(df["Data"], bins,
                             labels=["A" + str(x) for x in range(1, bins + 1)])
# Разбиваем на группы

df.loc[1:, "x"] = df.loc[1:, "Interval"].cat.codes + "-" + df["Interval"].shift().loc[1:]
res = (df
       .dropna(subset=["x"])
       .groupby("Interval")
       ["x"]
       .apply(lambda x: x.str.cat(sep="; ")))

# Выводим результаты

print(res)
print(my_list)
print(interval)
print(iv)
print(df_min_max)

Ответы (1 шт):

Автор решения: MaxU

Функция pd.cut() возвращает Series с категориальным типом данных. Чтобы избежать дальнейших проблем с типом category можно преобразовать его в строковой тип:

df["Interval"] = df["Interval"].astype(str)
df.loc[1:, "x"] = df.loc[1:, "Interval"] + "-" + df["Interval"].shift().loc[1:]

res = (df
       .dropna(subset=["x"])
       .groupby("Interval")
       ["x"]
       .apply(lambda x: x.str.cat(sep="; ")))

результат:

In [284]: res
Out[284]: 
Interval
A1    A1-A2; A1-A1; A1-A3; A1-A1
A2    A2-A3; A2-A2; A2-A1; A2-A2
A3    A3-A2; A3-A2; A3-A1; A3-A3
A4                  A4-A3; A4-A4
A6                         A6-A4
A7                         A7-A8
A8           A8-A6; A8-A9; A8-A8
A9                  A9-A8; A9-A7
Name: x, dtype: object
→ Ссылка