Python Pandas:读取Excel文件时如何指定数据类型?


72

我正在使用该pandas.read_excel()功能将Excel文件导入到熊猫数据框。

列之一是表格的主键:是所有数字,但以文本形式存储(Excel单元格左上角的绿色小三角形确认了这一点)。

但是,当我将文件导入pandas数据框时,该列将作为浮点导入。这意味着,例如“ 0614”变为614。

导入列时是否可以指定数据类型?我知道在导入CSV文件时这是可能的,但找不到的语法read_excel()

我能想到的唯一解决方案是在Excel中的文本开头添加一个任意字母(将“ 0614”转换为“ A0614”),以确保将列作为文本导入,然后切掉“ A”在python中,因此我可以将其与我从SQL导入的其他表进行匹配。

Answers:


113

您只需指定转换器。我创建了具有以下结构的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

我已经了解“转换器”指定了要应用于该列的函数。显然我错了-感谢您指出这一点,它非常有用!
Pythonista匿名

3
在哪里可以找到允许的转换器功能列表?我str在这里看到了,但大概还有int很多-在源文档的任何地方都存在一个链接,该链接枚举了可能的可用转换器函数?
Thomas Kimber

1
我也没有找到清单。由于“转换器”接受功能,因此我怀疑您的想像力是有限的,因此您只能在“转换器”功能的范围之内(即,它被设计为使用仅需要一个输入变量的功能!)。
tnknepp '16

奇怪的是,当我strconvertersdict中将列名设置为,然后打印时df.dtypes,该列的类型设置为objectnot str。有任何想法吗?甚至重要吗?
mhyousefi

1
@mhyousefi这并不重要(至少在表面上)。将列类型设置为字符串时,Pandas会将其称为对象。请在此处
tnknepp

41

从开始v0.20.0,函数中的dtype关键字参数read_excel()可用于指定需要应用于列的数据类型,就像 read_csv()情况一样。

在同一个列名上一起使用convertersdtype参数会导致后者变得模糊起来,而前者会获得优先选择。


1)为了使其不解释dtypes而是传递其列的所有内容(如它们原来在文件中一样),我们可以将此arg设置为str或,object以便不弄乱数据。(一种情况是数字前导零,否则将丢失)

pd.read_excel('file_name.xlsx', dtype=str)            # (or) dtype=object

2)它甚至支持dict映射,其中,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})

2
这应该是一个可以接受的答案,因为“转换器”似乎在将数据读取为其他类型之后会转换数据。这导致信息丢失(“ 001”将被读取为int(“ 001”)=“ 1”,然后转换为str。但是“ 001”!=“ 1”)。至少这就是我的情况,如果我错了,请纠正我。
Schorsch

9

read_excel()函数具有转换器参数,您可以在其中将函数应用于某些列中的输入。您可以使用它来将它们保留为字符串。 说明文件

用于在某些列中转换值的函数的字典。键可以是整数或列标签,值是具有一个输入参数,Excel单元格内容并返回转换后的内容的函数。

示例代码:

pandas.read_excel(my_file, converters = {my_str_column: str})

如果我们不知道工作表中存在的列数,有什么办法在阅读时将其应用于每一列?
探戈

6
得到了解决方案:converters = {col: str for col in column_list} df = pd.read_excel('some_excelfile.xls', converters=converters)
探戈

您可以按索引进行操作还是需要名称?例如,我正在读取没有标题的文件。
rrs '18

1
@rrs,您可以仅使用整数作为键而不是列名。
Nix GD

5

如果您不知道数据框中的列数和名称,则可以使用此方法:

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是您的列名的列表。


2
只是想知道是否df = df.astype(str)会更好(更简单)。
Petr Matuska '18年

1
为什么首先创建列表?使用起来可能更高效: conv = {x:str for x in pd.read_excel(fn,sheet_name='sheet1').columns}然后 df = pd.read_excel(fn,sheet_name='sheet1',converters=conv)
Dylan_w

3

如果您不知道列名,并且想为所有列指定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)

另外,nrows=1在第一个read_excel调用中添加内容可能会很有用,以避免不必仅获取标题就读取整个excel表。
努诺·安德烈

2

如果密钥的位数固定,可能应将其存储为文本而不是数字数据。您可以使用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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.