使用 read_excel 和转换器将 Excel 文件读入 Pandas DataFrame 会产生对象类型的数字列

Krz*_*ski 2 python excel dataframe pandas

我正在使用此处的代码片段阅读此 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')
Run Code Online (Sandbox Code Playgroud)

这导致Energy Supply列具有对象类型而不是浮点数。为什么会这样呢?

energy = energy_df()
print(energy.dtypes)

Energy Supply                object
Energy Supply per Capita    float64
% Renewable                 float64
Run Code Online (Sandbox Code Playgroud)

cs9*_*s95 5

让我们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'
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

您的数据无需转换器即可正常加载。有一个技巧可以帮助您理解为什么会发生这种情况。

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

pandas 将整数和字符串值传递给convert_energy,因此isinstance(energy, float)永远不会计算为True。相反,else运行和这些值按原样返回,因此结果列是字符串和整数的混合。如果你把 a 放在print(type(energy))你的函数中,这就会变得很明显。

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

所以,只是做——

df['Energy Supply'] *= 1000000
Run Code Online (Sandbox Code Playgroud)

就足够了。