将read_excel与转换器一起用于将Excel文件读取到Pandas DataFrame中会导致对象类型的数字列

发布于 2021-01-29 15:04:48

我正在使用以下代码段阅读此Excel文件“联合国能源指标”:

def convert_energy(energy):
    if isinstance(energy, float):
        return energy*1000000
    else:
        return energy

def energy_df():
    return pd.read_excel("Energy Indicators.xls", skiprows=17, skip_footer=38, usecols=[2,3,4,5], na_values=['...'], names=['Country', 'Energy Supply', 'Energy Supply per Capita', '% Renewable'], converters={1: convert_energy}).set_index('Country')

这将导致“ 能源供应” 列具有对象类型而不是浮点型。为什么会这样呢?

energy = energy_df()
print(energy.dtypes)

Energy Supply                object
Energy Supply per Capita    float64
% Renewable                 float64
关注者
0
被浏览
62
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    让我们converters暂时删除该参数-

    c = ['Energy Supply', 'Energy Supply per Capita', '% Renewable']
    df = pd.read_excel("Energy Indicators.xls", 
                       skiprows=17, 
                       skip_footer=38, 
                       usecols=[2,3,4,5], 
                       na_values=['...'], 
                       names=c,
                       index_col=[0])
    
    df.index.name = 'Country'
    
    
    
    df.head()    
                    Energy Supply  Energy Supply per Capita  % Renewable
    Country                                                             
    Afghanistan             321.0                      10.0    78.669280
    Albania                 102.0                      35.0   100.000000
    Algeria                1959.0                      51.0     0.551010
    American Samoa            NaN                       NaN     0.641026
    Andorra                   9.0                     121.0    88.695650
    
    df.dtypes
    
    Energy Supply               float64
    Energy Supply per Capita    float64
    % Renewable                 float64
    dtype: object
    

    没有转换器,数据加载就很好。有一个技巧可以理解为什么会发生这种情况。

    默认情况下,pandas将读入该列并尝试“解释”您的数据。通过指定自己的转换器,可以覆盖熊猫转换,因此不会发生这种情况。

    熊猫将整数和字符串值传递到了convert_energy,因此isinstance(energy, float)永远不会求到True。而是else运行,并且这些值按原样返回,因此您得到的列是字符串和整数的混合。如果print(type(energy))在函数内部放一个,这很明显。

    由于您混合使用类型,因此结果类型为object。但是,如果您不使用转换器,熊猫将尝试解释您的数据,并将成功将其解析为数字。

    因此,只需-

    df['Energy Supply'] *= 1000000
    

    会绰绰有余。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看