使用 Pandas 读取 CSV 时如何在列中保持前导零?

Posted

技术标签:

【中文标题】使用 Pandas 读取 CSV 时如何在列中保持前导零?【英文标题】:How to keep leading zeros in a column when reading CSV with Pandas? 【发布时间】:2012-10-26 08:20:42 【问题描述】:

我正在使用 read_csv 将研究数据导入 Pandas 数据框。

我的主题代码是 6 个数字编码,其中包括出生日期。对于我的一些科目,这会导致代码带有前导零(例如“010816”)。

当我导入 Pandas 时,前导零被去除,列格式为 int64

有没有办法将这个列原封不动地导入为字符串?

我尝试为该列使用自定义转换器,但它不起作用 - 似乎自定义转换发生在 Pandas 转换为 int 之前。

【问题讨论】:

Pandas read_csv dtype leading zeros的可能重复 【参考方案1】:

我认为您不能以您想要的方式指定列类型(如果最近没有更改并且 6 位数字不是可以转换为日期时间的日期)。您可以尝试使用np.genfromtxt() 并从那里创建DataFrame

编辑:看看 Wes Mckinney 的 blog,可能会有适合你的东西。 pandas 0.10 的新解析器似乎将于 11 月推出。

【讨论】:

该问题中的功能现在在 c-parser 分支上完成,应该会在 0.10 中出现。我刚刚对问题 #2184 进行了快速处理,并将很快包含在 0.9.1 中。但是,是的,使用 dtypes 应该是这里的首选行为,所以请在一个月左右的时间内留意 0.10。 如果你升级到 github master 上的最新版本(即使用转换器),你现在应该可以让它工作了 @ChangShe 谢谢,使用最新的 github 版本,我的转换器确实可以工作!期待 0.10 的更清洁的解决方案... Wes Mckinney 的博客页面是 404。【参考方案2】:

正如this question/answerLev Landau 所指出的,可能有一个简单的解决方案,可以在read_csv 函数中为某个列使用converters 选项。

converters='column_name': lambda x: str(x)

您可以参考pandas.io.parsers.read_csv documentation中read_csv函数的更多选项。

假设我有 csv 文件 projects.csv,如下所示:

project_name,project_id
Some Project,000245
Another Project,000478

例如下面的代码正在修剪前导零:

import csv
from pandas import read_csv

dataframe = read_csv('projects.csv')
print dataframe

结果:

me@ubuntu:~$ python test_dataframe.py 
      project_name  project_id
0     Some Project         245
1  Another Project         478
me@ubuntu:~$

解决方案代码示例:

import csv
from pandas import read_csv

dataframe = read_csv('projects.csv', converters='project_id': lambda x: str(x))
print dataframe

要求的结果:

me@ubuntu:~$ python test_dataframe.py 
      project_name project_id
0     Some Project     000245
1  Another Project     000478
me@ubuntu:~$

更新,因为它可以帮助他人:

要将所有列作为str,可以这样做(来自评论):

pd.read_csv('sample.csv', dtype = str)

要将大多数或选择性列作为str,可以这样做:

# lst of column names which needs to be string
lst_str_cols = ['prefix', 'serial']
# use dictionary comprehension to make dict of dtypes
dict_dtypes = x : 'str'  for x in lst_str_cols
# use dict on dtypes
pd.read_csv('sample.csv', dtype=dict_dtypes)

【讨论】:

如何给多列?? 对于多列:请参阅上述答案中的更新信息。谢谢。【参考方案3】:

这是一个更短、更强大且完全有效的解决方案:

只需定义变量名和所需数据类型之间的映射(字典):

dtype_dic= 'subject_id': str, 
            'subject_number' : 'float'

将该映射与pd.read_csv() 一起使用:

df = pd.read_csv(yourdata, dtype = dtype_dic)

瞧!

【讨论】:

您还可以包含许多其他数据类型,float 等。我相信这是最熊猫的解决方案 查询:在dtype_dic json中,为什么str不带引号但浮动在引号中? 我不得不遍历具有不同列的不同 CSV。此函数获取所有列映射,并且当表中没有列时不会出错。因此,我能够在一个dtype_dic 中定义所有不同表中的所有列(以字符串形式读取)并将其用于所有 csv。谢谢! 我相信这也是最好的解决方案:) 这对我不起作用(python3.6,pandas 0.22.0);我仍然丢失了前导零。【参考方案4】:

如果您有很多列并且您不知道哪些列包含可能会丢失的前导零,或者您可能只需要自动化您的代码。您可以执行以下操作:

df = pd.read_csv("your_file.csv", nrows=1) # Just take the first row to extract the columns' names
col_str_dic = column:str for column in list(df)
df = pd.read_csv("your_file.csv", dtype=col_str_dic) # Now you can read the compete file

你也可以这样做:

df = pd.read_csv("your_file.csv", dtype=str)

通过这样做,您将所有列都作为字符串,并且不会丢失任何前导零。

【讨论】:

【参考方案5】:

如果您知道宽度,可以使用converters 将数字转换为固定宽度。

比如宽度是5,那么

data = pd.read_csv('text.csv', converters='column1': lambda x: f"x:05")

这样就可以了。它适用于 pandas==0.23.0 和 read_excel

需要 Python3.6 或更高版本。

【讨论】:

【参考方案6】:

你可以做到这一点,适用于所有版本的 Pandas

pd.read_csv('filename.csv', dtype='zero_column_name': object)

【讨论】:

以上是关于使用 Pandas 读取 CSV 时如何在列中保持前导零?的主要内容,如果未能解决你的问题,请参考以下文章

导出为 CSV 时,如何在列中保留前导零?

如何使用 Pandas 在列中添加值的超链接?

pandas.read_csv() 可以在同一列中应用不同的日期格式!这是一个已知的错误吗?如何解决?

如何在 PHP 中解析 csv 在列中具有多行数据

Python Pandas:如何在列中搜索字符串? [复制]

Pandas 将 CSV 列中的 '\0' 读取为 NULL 字符并在 JSON 中打印为 Unicode