【问题标题】:TypeError: '<=' not supported between instances of 'int' and 'str' when doing Seaborn Histplot类型错误:在执行 Seaborn Histplot 时,“int”和“str”实例之间不支持“<=”
【发布时间】:2020-12-30 02:44:04
【问题描述】:

在创建不同直方图的子图时出现上述类型错误。

为了提供一些上下文,我有一个大型数据集,我必须将其分成几个单独的块进行清理以避免内存问题。我单独保存了每个块,然后在另一个笔记本上将它们连接在一起。

当我运行我的代码以使用分块数据帧创建子图时,它工作正常,但是当我再次使用连接数据运行子图代码时,我得到一个类型错误。我不明白为什么,因为我并没有真正改变任何东西。

错误发生在这里:

我的完整代码

#Overall
CRev_All_age1 = df_optimized.groupby(['YearOnboarded', 'age_buckets']).sum().reset_index()
#Europe
CRev_EU = df_optimized.loc[df_optimized['Continents'] == 'Europe']
Plot_CRev_EU_age1 = CRev_EU.groupby(['YearOnboarded', 'age_buckets']).sum().reset_index()
#Asia
CRev_Asia = df_optimized.loc[df_optimized['Continents'] == 'Asia']
Plot_CRev_Asia_age1 = CRev_Asia.groupby(['YearOnboarded', 'age_buckets']).sum().reset_index()
#Other
CRev_Other = df_optimized.loc[(df_optimized['Continents'] != 'Europe') & (df_optimized['Continents'] != 'Asia')]
Plot_CRev_Other_age1 = CRev_Other.groupby(['YearOnboarded', 'age_buckets']).sum().reset_index()

fig, axes = plt.subplots(2,2, constrained_layout=True, figsize=(14,12))
ax1, ax2, ax3, ax4 =axes.flatten()

#plot1
ax1 = sns.histplot( data=CRev_All_age1, x="YearOnboarded", hue="age_buckets",weights="Revenue2", multiple="stack", discrete=True, shrink=.9, ax=ax1)
ax1.set_title('Overall - Client Revenue (Million)', fontsize=16, fontweight='bold')
ax1.tick_params('x', labelrotation=15)
ax1.set_ylabel('Revenue', fontsize=12)
ax1.set_xlabel('Year Onboarded', fontsize=12)
#plot2
ax2 = sns.histplot( data=Plot_CRev_EU_age1, x="YearOnboarded", hue="age_buckets",weights="Revenue2", multiple="stack", discrete=True, shrink=.9, ax=ax2)
ax2.set_title('Europe - Client Revenue (Million)', fontsize=14, fontweight='bold')
plt.setp(ax2.xaxis.get_majorticklabels(), rotation=15)
ax2.set_ylabel('Revenue', fontsize=12)
ax2.set_xlabel('Year Onboarded', fontsize=12)
#plot3
ax3 = sns.histplot( data=Plot_CRev_Asia_age1, x="YearOnboarded", hue="age_buckets",weights="Revenue2", multiple="stack", discrete=True, shrink=.9, ax=ax3)
ax3.set_title('Asia - Client Revenue (Million)', fontsize=14, fontweight='bold')
for tick in ax3.get_xticklabels():
    tick.set_rotation(15)
ax3.set_ylabel('Revenue', fontsize=12)
ax3.set_xlabel('Year Onboarded', fontsize=12)
#plot4
ax4 = sns.histplot( data=Plot_CRev_Other_age1, x="YearOnboarded", hue="age_buckets",weights="Revenue2", multiple="stack", discrete=True, shrink=.9, ax=ax4)
ax4.set_title('Other Continents - Client Revenue (Million)', fontsize=14, fontweight='bold')
ax4.tick_params(labelrotation=15)
ax4.set_ylabel('Revenue', fontsize=12)
ax4.set_xlabel('Year Onboarded', fontsize=12)

plt.show()

玩具数据

dataset = {'YearOnboarded': [2018,2019,2020,2016,2019,2020,2017,2019,2020,2018,2019,2020,2016,2016,2016,2017,2016,2018,2016],
           'Revenue2': [100,50,25,30,40,50,60,100,20,40,100,20,5,5,8,4,10,20,8],
           'age_buckets': ['18-30','30-39','40-49','50-59','18-30','30-39','40-49','50-59','18-30','30-39','40-49','50-59',
                           '18-30','30-39','40-49','50-59','18-30','30-39','40-49'],
           'Continents': ['Europe','Asia','Africa','Africa','Other','Asia','Africa','Other','America','America','Europe','Europe',
                      'Other','Europe','Asia','Africa','Asia','Europe','Other']}
df_optimized = pd.DataFrame(data=dataset)

如果有人能帮助我理解为什么会发生这种情况以及如何解决问题,我将不胜感激。

谢谢!

编辑:找到问题的根源以及解决方法。将每个块数据集导入新内核时,一列具有混合数据类型。使用.astype('category') 转换具有混合数据类型的列并没有解决我的问题,因此我必须在使用read_csv dtype 导入数据时更改数据类型,并且它起作用了。

【问题讨论】:

  • 嗨,CRev_All_age1确实有一个Revenue2列。我更新了我的问题以添加一个玩具数据集,但我无法使用玩具数据复制错误消息,因为我的代码有效。
  • 也许您的真实数据在某处包含字符串而不是数字?打印出CRev_All_age1.info() 和类似的,可能会有所帮助。如果“Revenue2”在某处(以及其他地方的整数)包含一个字符串,则您的错误消息是可重复的。
  • 我仅有的数据类型是 float64、int64 和 object。但在连接之前,它曾经运行良好。
  • 所以你的意思是,在连接我的分块数据帧后,当所有分块数据帧具有相同的数据类型时,可能会出现一个字符串?
  • 类型“object”表示字符串,不适用于"Revenue2"列。您的玩具数据只有 integerobject 列。哪一列的类型是float64?顺便问一下,你用的是最新的 seaborn 版本(0.11)吗?

标签: python pandas seaborn


【解决方案1】:

此问题可能源于 Revenue2 中的一个字符,当从您用于保存数据块的任何文件类型加载数据时,pandas 无法将其识别为整数。即使列中只有一个元素不能解释为整数,pandas 也会将整列作为对象读取。在示例中,我使用了- 来表示此字符串字符,没有等效整数。
如果你运行这段代码:

import pandas as pd
import seaborn as sns
df = pd.DataFrame({'YearOnboarded': [2018,2019,2020,2016,2019,2020,2017,2019,2020,2018,2019,2020,2016,2016,2016,2017,2016,2018,2016],
           'Revenue2': ["-",50,25,30,40,50,60,100,20,40,100,20,5,5,8,4,10,20,8],
           'age_buckets': ['18-30','30-39','40-49','50-59','18-30','30-39','40-49','50-59','18-30','30-39','40-49','50-59',
                           '18-30','30-39','40-49','50-59','18-30','30-39','40-49'],
           'Continents': ['Europe','Asia','Africa','Africa','Other','Asia','Africa','Other','America','America','Europe','Europe',
                      'Other','Europe','Asia','Africa','Asia','Europe','Other']})

df['Revenue2'] = df['Revenue2'].astype(int)

你会得到这个错误:

ValueError: invalid literal for int() with base 10: '-'

这很有帮助,因为它指示第一个违规字符,然后您可以用填充符替换该字符,然后重试:

df['Revenue2'] = df.Revenue2.astype(str).str.replace('-','0').astype(int)
df['Revenue2'] = df['Revenue2'].astype(int)

最终,我认为您应该能够删除所有无效字符,并拥有一个全为整数的列。

【讨论】:

  • 感谢您的回答非常有用。我以不同的方式解决了这个问题,我发现一列中有混合数据类型,然后导致错误。所以我在导入数据时指定了dtype,它解决了这个问题。
  • 我很高兴它成功了,并且您找到了更好的解决方案。也许你可以发布你的答案?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-14
  • 2021-09-28
  • 2019-10-24
  • 2020-05-19
相关资源
最近更新 更多