python - Pandas read_excel函数忽略dtype

标签 python excel pandas

我正在尝试使用 pd.read_excel() 读取 excel 文件。
excel 文件有 2 列日期和时间,我想将这两列读取为 str 而不是 excel dtype。
excel文件示例
Example of the excel file
我试图指定 dtype 或转换器参数无济于事。

df = pd.read_excel('xls_test.xlsx',
                   dtype={'Date':str,'Time':str})
df.dtypes
Date    object
Time    object
dtype: object
df.head()
Date    Time
0   2020-03-08 00:00:00 10:00:00
1   2020-03-09 00:00:00 11:00:00
2   2020-03-10 00:00:00 12:00:00
3   2020-03-11 00:00:00 13:00:00
4   2020-03-12 00:00:00 14:00:00

如您所见,日期列不被视为字符串...
使用转换器时也是如此
df = pd.read_excel('xls_test.xlsx',
                   converters={'Date':str,'Time':str})
df.dtypes
Date    object
Time    object
dtype: object
df.head()
Date    Time
0   2020-03-08 00:00:00 10:00:00
1   2020-03-09 00:00:00 11:00:00
2   2020-03-10 00:00:00 12:00:00
3   2020-03-11 00:00:00 13:00:00
4   2020-03-12 00:00:00 14:00:00

我也尝试过使用其他引擎,但结果总是一样的。
dtype 参数似乎在读取 csv 时按预期工作
我在这里做错了什么?
编辑:
我忘了提,我使用的是 pandas 1.2.2 的最新版本,但在从 1.1.2 更新之前遇到了同样的问题。

最佳答案

您遇到的问题是 excel 中的单元格具有数据类型。所以这里的数据类型是日期或时间,它的格式仅用于显示。 “直接”加载它意味着加载日期时间类型*。
这意味着,无论你用 dtype= 做什么参数,数据将作为日期加载,然后转换为字符串,为您提供您看到的结果 :

>>> pd.read_excel('test.xlsx').head()
        Date      Time            Datetime
0 2020-03-08  10:00:00 2020-03-08 10:00:00
1 2020-03-09  11:00:00 2020-03-09 11:00:00
2 2020-03-10  12:00:00 2020-03-10 12:00:00
3 2020-03-11  13:00:00 2020-03-11 13:00:00
4 2020-03-12  14:00:00 2020-03-12 14:00:00
>>> pd.read_excel('test.xlsx').dtypes
Date        datetime64[ns]
Time                object
Datetime    datetime64[ns]
dtype: object
>>> pd.read_excel('test.xlsx', dtype='string').head()
                  Date      Time             Datetime
0  2020-03-08 00:00:00  10:00:00  2020-03-08 10:00:00
1  2020-03-09 00:00:00  11:00:00  2020-03-09 11:00:00
2  2020-03-10 00:00:00  12:00:00  2020-03-10 12:00:00
3  2020-03-11 00:00:00  13:00:00  2020-03-11 13:00:00
4  2020-03-12 00:00:00  14:00:00  2020-03-12 14:00:00
>>> pd.read_excel('test.xlsx', dtype='string').dtypes
Date        string
Time        string
Datetime    string
dtype: object
只有在 csv 文件中,日期时间数据才以字符串形式存储在文件中。在那里,将它“直接”作为字符串加载是有意义的。在 excel 文件中,您也可以将其加载为日期并将其格式化为 .dt.strftime()

这并不是说您无法加载格式化的数据,但您需要 2 个步骤:
  • 加载数据
  • 重新应用格式

  • 格式化类型之间需要进行一些转换,您不能直接使用 pandas - 但是您可以使用 pandas 用作后端的引擎:
    import datetime
    import openpyxl
    import re
    
    date_corresp = {
        'dd': '%d',
        'mm': '%m',
        'yy': '%y',
        'yyyy': '%Y',
    }
    
    time_corresp = {
        'hh': '%h',
        'mm': '%M',
        'ss': '%S',
    }
    
    def datecell_as_formatted(cell):
        if isinstance(cell.value, datetime.time):
            dfmt, tfmt = '', cell.number_format
        elif isinstance(cell.value, (datetime.date, datetime.datetime)):
            dfmt, tfmt, *_ = cell.number_format.split('\\', 1) + ['']
        else:
            raise ValueError('Not a datetime cell')
    
        for fmt in re.split(r'\W', dfmt):
            if fmt:
                dfmt = re.sub(f'\\b{fmt}\\b', date_corresp.get(fmt, fmt), dfmt)
    
        for fmt in re.split(r'\W', tfmt):
            if fmt:
                tfmt = re.sub(f'\\b{fmt}\\b', time_corresp.get(fmt, fmt), tfmt)
    
        return cell.value.strftime(dfmt + tfmt)
    
    然后您可以按如下方式使用它:
    >>> wb = openpyxl.load_workbook('test.xlsx')
    >>> ws = wb.worksheets[0]
    >>> datecell_as_formatted(ws.cell(row=2, column=1))
    '08/03/20'
    
    (如果不完整,您也可以使用更多日期/时间格式项目来完成 _corresp 字典)

    * 它存储为浮点数,即自 1900 年 1 月 1 日以来的天数,您可以通过将日期格式化为数字或在 this excelcampus page 上看到.

    关于python - Pandas read_excel函数忽略dtype,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66260248/

    相关文章:

    python - Web 编程中的常见模式是什么?

    python - 在 Python 中将字符串列表转换为整数(或 double )

    python - 将超链接添加到由 pandas dataframe to_excel 方法创建的 excel 表

    python - 为什么 sklearn 训练/测试分割加上 PCA 会使我的标签不正确?

    java - jython 独立 jar 减少了软件包列表?

    python - Pandas :如何在groupby之后获得特定的群体?

    excel - 在 Blueprism 中获取命名范围作为集合

    excel - 将Excel中一列中的所有值乘以一个数字

    python - Dataframe 按特定列分组,其他列的 aggerage 比率?

    python - Pandas:将特定列值拆分为新列,并在所有新创建的列中查找某个值的出现次数