Python: аргумент float() должен быть строкой или числом, а не пандами

Имейте следующий фрагмент кода, с помощью которого я пытаюсь построить график:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import mpld3



my_list = [1,2,3,4,5,7,8,9,11,23,56,78,3,3,5,7,9,12]

new_list = pd.Series(my_list)

df1 = pd.DataFrame({'Range1':new_list.value_counts().index, 'Range2':new_list.value_counts().values})

df1.sort_values(by=["Range1"],inplace=True)

df2 = df1.groupby(pd.cut(df1["Range1"], [0,1,2,3,4,5,6,7,8,9,10,11,df1['Range1'].max()])).sum()

objects = df2['Range2'].index

y_pos = np.arange(len(df2['Range2'].index))

plt.bar(df2['Range2'].index.values, df2['Range2'].values)

но получая следующее сообщение об ошибке:

TypeError: float() argument must be a string or a number, not 'pandas._libs.interval.Interval'

Не получается понять, откуда эта ошибка с плавающей запятой. Любое предложение высоко ценится.


person Alpha001    schedule 04.12.2018    source источник


Ответы (2)


Matplotlib не может отображать category типы данных. Вам нужно будет преобразовать в строку.

plt.bar(df2['Range2'].index.astype(str), df2['Range2'].values)

введите здесь описание изображения

person ImportanceOfBeingErnest    schedule 04.12.2018

Операция pd.cut дает интервалы:

In [11]: pd.cut(df1["Range1"], [0,1,2,3,4,5,6,7,8,9,10,11,df1['Range1'].max()])
Out[11]:
12      (0, 1]
11      (1, 2]
0       (2, 3]
10      (3, 4]
3       (4, 5]
2       (6, 7]
9       (7, 8]
1       (8, 9]
8     (10, 11]
7     (11, 78]
5     (11, 78]
4     (11, 78]
6     (11, 78]
Name: Range1, dtype: category
Categories (12, interval[int64]): [(0, 1] < (1, 2] < (2, 3] < (3, 4] ... (8, 9] < (9, 10] < (10, 11] <
                                   (11, 78]]

При использовании в операции groupby они сопоставляются на основе индекса операции вырезания выше, а затем группируются и суммируются в соответствии с указанной вами операцией.

В результате интервалы заканчиваются индексом в df2:

In [14]: df2
Out[14]:
          Range1  Range2
Range1
(0, 1]         1       1
(1, 2]         2       1
(2, 3]         3       3
(3, 4]         4       1
(4, 5]         5       2
(5, 6]         0       0
(6, 7]         7       2
(7, 8]         8       1
(8, 9]         9       2
(9, 10]        0       0
(10, 11]      11       1
(11, 78]     169       4

Когда вы используете df2['Range2'].index.values, это будет array из этих интервалов, переданных в качестве первого аргумента bar, который не может быть преобразован в число с плавающей запятой, как ожидает matplotlib.

Если вы хотите просто построить гистограмму df2.Range2 и вас устраивает интервалы в качестве меток осей, это сработает:

plt.bar(range(len(df2)), df2.Range2.values, tick_label=df2.Range2.index.values)

и создает для меня это изображение:

введите здесь описание изображения

person ely    schedule 04.12.2018