Pandas 系列不根据第一个条目以科学记数法显示小数字

Pandas series not showing small numbers in scientific notation depending on first entry

更新:

我找到了错误来源:在当前版本的pandas中,具有列'object' dtype 的数据帧不再使用科学记数法。对于大值,单元格显示正确的有效数字,但对于小数字,显示的值为 0.0.

如果您从 运行 脚本访问单元格,您仍然可以获得正确的值。问题是,如果您将数据框存储为文本文件,则会保存不正确的值。

这是一个代码示例,在以前的版本中具有正确的(对我而言)行为:

import pandas as pd
print(f'pandas version {pd.__version__}')

idx = 'H1_6563A'
data = {'ion': 'H1',
        'wavelength': 6563.0,
        'latex_label': '63\AA\,HI$',
        'intgr_flux': 3.128572e-14,
        'dist': 2.8e20,
        'eqw': 1464.05371}

mySeries = pd.Series(index=data.keys(), dtype='object')
for param, value in data.items():
    mySeries[param] = value
print(f'\nSeries: \n {mySeries}')

myDF = pd.DataFrame(columns=data.keys())
myDF.loc[idx] = mySeries
print(f'\nDataFrame:\n {myDF}')

其中数据框显示科学和非科学浮点数的组合:

pandas version 1.2.3

Series: 
 ion                                 H1
wavelength                      6563.0
latex_label              63\AA\,HI$
intgr_flux                         0.0
dist           280000000000000000000.0
eqw                         1464.05371
dtype: object

DataFrame:
          ion  wavelength    latex_label    intgr_flux          dist         eqw
H1_6563A  H1      6563.0  63\AA\,HI$  3.128572e-14  2.800000e+20  1464.05371

pandas 1.4.1 中的相同脚本 returns:

pandas version 1.4.1

Series: 
 ion                                 H1
wavelength                      6563.0
latex_label              63\AA\,HI$
intgr_flux                         0.0
dist           280000000000000000000.0
eqw                         1464.05371
dtype: object

DataFrame:
          ion wavelength    latex_label intgr_flux                     dist         eqw
H1_6563A  H1     6563.0  63\AA\,HI$        0.0  280000000000000000000.0   1464.05371  

我想知道是否有人愿意分享他们复制原始行为的方法,这样我就可以拥有一个包含混合变量(字符串、整数、浮点数、None、科学的、非科学的)的数据框并显示更正有效数字。

非常感谢。

原始问题

我正在使用 pandas.Series 作为不同类型条目的容器。我在用科学记数法声明小浮点数时注意到以下问题:

import numpy as np
import pandas as pd

print(f'Pandas {pd.__version__}')

columns = ['c0', 'c1', 'c2', 'c3']
mySeries = pd.Series(index=columns)

mySeries['c0'] = 'None'
mySeries['c1'] = np.nan
mySeries['c2'] = 1234.0
mySeries['c3'] = 1.234e-18

print(mySeries)

哪个returns:

c0      None
c1       NaN
c2    1234.0
c3       0.0
dtype: object

将 'c3' 条目称为 returns 完整的浮点数,但是,如果将此系列转换为 pandas.DataFrame 并将其保存到文本文件(使用 .to_string() 属性)它将被存储为 0.0.

如果您的第一个条目是浮点数,则不会发生这种情况:

columns = ['c0', 'c1', 'c2', 'c3']
mySeries = pd.Series(index=columns)

mySeries['c0'] = 123
mySeries['c1'] = np.nan
mySeries['c2'] = 1234.0
mySeries['c3'] = 1.234e-18

print(mySeries)

c0    1.230000e+02
c1             NaN
c2    1.234000e+03
c3    1.234000e-18
dtype: float64

所以我的问题是:哪种方法是声明输入变量 dtype 的正确方法,这样输入顺序就不会影响显示。另外,不知道有没有人知道决定细胞是否使用科学记数法的参数是什么

非常感谢。

您应该在创建系列时指定数据类型,例如

mySeries = pd.Series(index=columns, dtype='float64')

如果您不这样做,系统可能会根据您设置的第一个值进行推断。

有关详细信息,请参阅 https://pandas.pydata.org/docs/reference/api/pandas.Series.html#pandas-series

更新

看起来当 python 浮点数存储为 dtype 'object' 时,字符串表示不使用科学记数法并截断为小数点后大约六位数字。根据您的观点,这可能是一个错误。

您在两个系列之间观察到的行为差异是由于您的第二个系列包含所有数字,因此 dtype 为 'float64'。您的第一个系列包含 'None',它是一个字符串,因此 dtype 是 'object'。如果您必须将字符串和数字存储在同一个系列中,我会使用 'string' dtype 并将所有内容存储为字符串。

我会先用适当的 dtype 塑造我的 df,然后添加数据:

import pandas as pd

df = pd.DataFrame(
    {'ion': pd.Series(dtype='str'), 
     'wavelength': pd.Series(dtype='float'), 
     'intgr_flux': pd.Series(dtype='float')})

idx = 'H1_6563A'
data = {
    'ion': 'H1',
    'wavelength': 6563.0,
    'intgr_flux': 3.128572e-14}

df.loc[idx] = data
print(df)

# Outputs:
#         ion  wavelength    intgr_flux
# H1_6563A  H1      6563.0  3.128572e-14