Python pandas:读取Excel文件时如何指定数据类型?
- 2025-02-18 09:23:00
- admin 原创
- 187
问题描述:
我正在使用该函数将 excel 文件导入 pandas 数据框pandas.read_excel()
。
其中一列是表的主键:它全部都是数字,但以文本形式存储(Excel 单元格左上角的小绿色三角形证实了这一点)。
但是,当我将文件导入 pandas 数据框时,该列会作为浮点数导入。这意味着,例如,“0614”会变成 614。
导入列时是否可以指定数据类型?我知道导入 CSV 文件时可以这样做,但在语法中找不到任何内容read_excel()
。
我能想到的唯一解决方案是在 Excel 中在文本开头添加一个任意字母(将“0614”转换为“A0614”),以确保该列作为文本导入,然后在 python 中砍掉“A”,这样我就可以将其与我从 SQL 导入的其他表匹配。
解决方案 1:
您只需指定转换器。我创建了一个具有以下结构的 Excel 电子表格:
names ages
bob 05
tom 4
suzy 3
其中“年龄”列被格式化为字符串。要加载:
import pandas as pd
df = pd.read_excel('Book1.xlsx',sheetname='Sheet1',header=0,converters={'names':str,'ages':str})
>>> df
names ages
0 bob 05
1 tom 4
2 suzy 3
解决方案 2:
从开始v0.20.0
,函数dtype
中的关键字参数read_excel()
可用于指定需要应用于列的数据类型,就像 read_csv()
案例中的那样。
在同一列名上同时使用converters
和dtype
参数将导致后者被遮蔽而前者获得优先。
1)为了使它不解释dtypes
而是传递其列的所有内容,因为它们最初存在于文件中,我们可以将这个参数设置为str
或,object
这样我们就不会弄乱我们的数据。(一种这样的情况是数字中的前导零,否则这些零将会丢失)
pd.read_excel('file_name.xlsx', dtype=str) # (or) dtype=object
2)它甚至支持字典映射,其中keys
构成列名及其values
各自的数据类型,特别是当您想要改变dtype
所有列的子集时。
# Assuming data types for `a` and `b` columns to be altered
pd.read_excel('file_name.xlsx', dtype={'a': np.float64, 'b': np.int32})
解决方案 3:
如果您能够正确读取 excel 文件,但只有整数值没有显示,您可以这样指定。
df = pd.read_excel('my.xlsx',sheetname='Sheet1', engine="openpyxl", dtype=str)
这会将您的整数值更改为字符串并显示在数据框中
解决方案 4:
如果您不知道数据框中列的数量和名称,那么这种方法会很方便:
column_list = []
df_column = pd.read_excel(file_name, 'Sheet1').columns
for i in df_column:
column_list.append(i)
converter = {col: str for col in column_list}
df_actual = pd.read_excel(file_name, converters=converter)
其中 column_list 是列名列表。
解决方案 5:
read_excel() 函数有一个转换器参数,您可以在其中将函数应用于某些列中的输入。您可以使用它将它们保存为字符串。
文档:
用于转换特定列中的值的函数字典。键可以是整数或列标签,值是接受一个输入参数(Excel 单元格内容)并返回转换后内容的函数。
示例代码:
pandas.read_excel(my_file, converters = {my_str_column: str})
解决方案 6:
如果您不知道列名并且想要为所有列指定str数据类型:
table = pd.read_excel("path_to_filename")
cols = table.columns
conv = dict(zip(cols ,[str] * len(cols)))
table = pd.read_excel("path_to_filename", converters=conv)
解决方案 7:
如果您的密钥有固定位数,您可能应该将其存储为文本而不是数字数据。您可以使用converters
参数或read_excel
来实现这一点。
或者,如果这不起作用,只需在将数据读入数据框后对其进行操作:
df['key_zfill'] = df['key'].astype(str).str.zfill(4)
names key key_zfill
0 abc 5 0005
1 def 4962 4962
2 ghi 300 0300
3 jkl 14 0014
4 mno 20 0020
解决方案 8:
converters
或dtype
并不总是有帮助。特别是对于日期/时间和持续时间(理想情况下是两者的混合......),后处理是必要的。在这种情况下,将 Excel 文件的内容读取为内置类型并从中创建 DataFrame 可能是一种选择。
以下是示例文件。“duration”列包含 HH:MM:SS 格式的持续时间值和无效值“-”。
如果小时数小于 24,Excel 会将条目格式化为时间,否则格式化为持续时间。我们想要timedelta
DataFrame 中整个列的 dtype。但pandas
导入时出错了:
import pandas as pd
df = pd.read_excel("path-to-file")
df.duration
# 0 12:30:00
# 1 1900-01-01 00:30:00
# 2 -
# 3 1900-01-01 23:55:01
# Name: duration, dtype: object
[type(i) for i in df.duration]
# [datetime.time, datetime.datetime, str, datetime.datetime]
现在我们有了 datetime.datetime 和 datetime.time 对象,要取回持续时间 (timedelta)就太难了converter
!您可以直接用 来做,但这并不会降低难度。
在这里,我发现直接使用 Excel 加载引擎实际上更容易:
from openpyxl import load_workbook
wb = load_workbook('path-to-file')
sheet = wb['Tests'] # adjust sheet name, this is for the demo file
data = list(sheet.values) # a list of tuples, one tuple for each row
df = pd.DataFrame(data[1:], columns=data[0]) # first tuple is column names
df['duration']
# 0 12:30:00
# 1 1 day, 0:30:00
# 2 -
# 3 1 day, 23:55:01
# Name: duration, dtype: object
[type(i) for i in df['duration']]
# [datetime.time, datetime.timedelta, str, datetime.timedelta]
现在我们已经有一些 timedelta 对象了!其他对象到 timedelta 的转换非常简单,只需
df['duration'] = pd.to_timedelta(df.duration.astype(str), errors='coerce')
df['duration']
# 0 0 days 12:30:00
# 1 1 days 00:30:00
# 2 NaT
# 3 1 days 23:55:01
# Name: duration, dtype: timedelta64[ns]
解决方案 9:
令我惊讶的是,其他答案都没有提到 read_excel 的 N/A 解析。某些字符串(''、'#N/A'、'#N/AN/A'、'#NA'、'-1.#IND'、'-1.#QNAN'、'-NaN'、'-nan'、'1.#IND'、'1.#QNAN'、''、'N/A'、'NA'、'NULL'、'NaN'、'None'、'n/a'、'nan'、'null')被解释为 NaN,即使设置了 dtype 或转换器也是如此。要准确获取 Excel 表中的文本,可以设置 na_filter=False。
df = pd.read_excel('file.xlsx', dtype={'col1':str, 'col2':str}, na_filter=False)
Pandas 文档在这里。
扫码咨询,免费领取项目管理大礼包!