TypeError со смешанными dtypes при построении кадра данных - PullRequest
0 голосов
/ 25 марта 2020

Я пробую базовый пример c seaborn, и он работает:

fig, ax = plt.subplots()
sns.set(style="whitegrid")
tips = sns.load_dataset("tips")
sns.violinplot(ax=ax, x="day", y="total_bill", data=tips)

Я пытаюсь написать что-то похожее на созданном мною кадре:

names = np.array(["Class 1", 'Class 2'])
aa = names[np.random.randint(0,2,100)]
bb = np.random.uniform(0,1,100)
df = pd.DataFrame(np.array([aa, bb]).T, columns=["key", "value"])
fig, ax = plt.subplots()
sns.violinplot(ax=ax, data=df, x="key", y="value")

и выдает длинная ошибка, оканчивающаяся на:

/opt/anaconda3/envs/py36nest/lib/python3.6/site-packages/numpy/core/_methods.py in _mean(a, axis, dtype, out, keepdims)
     76     if isinstance(ret, mu.ndarray):
     77         ret = um.true_divide(
---> 78                 ret, rcount, out=ret, casting='unsafe', subok=False)
     79         if is_float16_result and out is None:
     80             ret = arr.dtype.type(ret)

TypeError: unsupported operand type(s) for /: 'str' and 'int'

Какого черта я делаю не так? Кадр данных выглядит корректно, когда я его отображаю

РЕДАКТИРОВАТЬ : я обнаружил, что если я строю свой DataFrame другим способом, он работает без ошибок

df = pd.DataFrame({"key" : aa, "value" : bb})

Whyyyyy ????

1 Ответ

1 голос
/ 26 марта 2020

Есть несколько способов решить вашу проблему или ответить на ваш вопрос, но я представлю три метода.

Как вы и думали, ваша основная проблема заключается в том, как вы создаете свой фрейм данных, в частности, как вы вызываете np.array внутри DataFrame(), который преобразует весь массив в один dtype. Как уже упоминали другие пользователи, вы можете обойти это, используя pandas Series, списки или формат словаря, который вы используете.

Каждое из следующих действий работает для меня:

Метод 1: серия

names = np.array(["Class 1", 'Class 2'])
aa = names[np.random.randint(0,2,100)]
bb = np.random.uniform(0,1,100)
# df = pd.DataFrame(np.array([aa, bb]).T, columns=["key", "value"]) #YOUR OLD CODE

#USING SERIES (slowest but easiest to understand)
aa_series = pd.Series(aa, name = 'key') #the name of the series can turn into column names (or index names depending on method of concatenation)
bb_series = pd.Series(bb, name = 'value')

df = pd.DataFrame([aa_series,bb_series]).T #transpose to match a realistic format


fig, ax = plt.subplots()
sns.violinplot(ax=ax, data=df, x="key", y="value")

Метод 2: понимание списка


names = np.array(["Class 1", 'Class 2'])
aa = names[np.random.randint(0,2,100)]
bb = np.random.uniform(0,1,100)
# df = pd.DataFrame(np.array([aa, bb]).T, columns=["key", "value"]) #YOUR OLD CODE

#USING LIST COMPREHENSION (faster, not as easy to get)

data = [[aa[i],bb[i]] for i in range(len(aa))] #put the data into 2 cols "manually"
df = pd.DataFrame(data, columns=["key", "value"]) 

fig, ax = plt.subplots()
sns.violinplot(ax=ax, data=df, x="key", y="value")

Метод 3: метод словаря Обновление Вы представили.

Лично я считаю, что метод Series проще всего следовать и работать с pandas, но все три должны дать вам результат, который вы ищете.

...