Pandas 将 csv 读取为字符串类型

Pandas reading csv as string type

提问人:daver 提问时间:6/8/2013 最后编辑:sophrosdaver 更新时间:3/3/2023 访问量:178405

问:

我有一个带有字母数字键的数据框,我想将其保存为 csv 并稍后回读。由于各种原因,我需要将此键列显式读取为字符串格式,我有严格的数字键,甚至更糟,例如:1234E5,Pandas 将其解释为浮点数。这显然使密钥完全无用。

问题是当我为数据框或其任何列指定字符串 dtype 时,我只会得到垃圾。我这里有一些示例代码:

df = pd.DataFrame(np.random.rand(2,2),
                  index=['1A', '1B'],
                  columns=['A', 'B'])
df.to_csv(savefile)

数据框如下所示:

           A         B
1A  0.209059  0.275554
1B  0.742666  0.721165

然后我是这样读的:

df_read = pd.read_csv(savefile, dtype=str, index_col=0)

结果是:

   A  B
B  (  <

这是我的电脑有问题,还是我在这里做错了什么,或者只是一个错误?

python pandas 类型转换 dtype

评论

0赞 Sami Start 2/21/2019
如果您能说出要将其保存为字符串的“各种原因”,那就太好了。上下文可能有助于找到更优雅的解决方案。
0赞 sophros 8/18/2020
这回答了你的问题吗?将 pandas 数据帧列导入为字符串,而不是 int
0赞 dank8 3/3/2023
这回答了你的问题吗?获取pandas.read_csv以将空值读取为空字符串而不是 nan

答:

67赞 Andy Hayden 6/8/2013 #1

更新:此问题已修复:从 0.11.1 开始,您传递 str/np.str 将等同于使用 object

使用对象 dtype:

In [11]: pd.read_csv('a', dtype=object, index_col=0)
Out[11]:
                      A                     B
1A  0.35633069074776547     0.745585398803751
1B  0.20037376323337375  0.013921830784260236

或者更好的是,只是不要指定 dtype:

In [12]: pd.read_csv('a', index_col=0)
Out[12]:
           A         B
1A  0.356331  0.745585
1B  0.200374  0.013922

但是绕过类型嗅探器并真正返回字符串需要 hacky 使用:converters

In [13]: pd.read_csv('a', converters={i: str for i in range(100)})
Out[13]:
                      A                     B
1A  0.35633069074776547     0.745585398803751
1B  0.20037376323337375  0.013921830784260236

其中,某个数字等于或大于列总数。100

最好避免使用 str dtype,例如,请参阅此处

评论

1赞 Jeff 6/8/2013
我认为应该 a) 提出无效传递的 dtype,以及 b) 只是将 dtype 转换为,打开一个问题?read_csvstrobject
1赞 daver 6/8/2013
谢谢,我会试试的。我已经提到我不能在不指定类型的情况下读入它,Pandas 不断采用我需要作为字符串的数字键并将它们解析为浮点数。就像我在示例中说的,像 1234E5 这样的键被理解为:1234.0x10^5,当我去查找它时,这对我没有任何帮助。
0赞 Andy Hayden 6/8/2013
@daver,当它(很快)出来时,这个问题会在 0.11.1 中修复。谢谢!
1赞 elPastor 11/8/2016
简单地包括(而不是index_col)已经解决了我所有前导零消失的问题。dtype=object
3赞 Anton Tarasenko 6/2/2017
设置是不够的。例如,抛出一个错误,因为熊猫在途中被迫到某个地方。dtypedf.applymap(lambda x: x.strip())AttributeError: ("'float' object has no attribute 'strip'", 'occurred at index A')objectfloat
13赞 Chris Conlan 9/4/2018 #2

就像 Anton T 在他的评论中所说的那样,将使用其类型嗅探器随机将类型转换为类型,即使您传递 、 或 .pandasobjectfloatdtype=objectdtype=strdtype=np.str

由于您可以传递函数字典,其中键是列索引,值是转换器函数,因此您可以执行类似操作(例如,对于 100 列)。

pd.read_csv('some_file.csv', converters={i: str for i in range(0, 100)})

如果您不知道将读取多少列,您甚至可以传递比列数大得多的 N。range(0, N)

评论

0赞 Julio Batista Silva 6/5/2020
我在版本“0.25.3”中收到“IndexError:列表索引超出范围”
4赞 danielrs 4/11/2019 #3

如果您事先不知道任何列,请使用适用于任何列的转换器:

import pandas as pd

class StringConverter(dict):
    def __contains__(self, item):
        return True

    def __getitem__(self, item):
        return str

    def get(self, default=None):
        return str

pd.read_csv(file_or_buffer, converters=StringConverter())
0赞 sophros 8/18/2020 #4

上面的许多答案都很好,但既不是很优雅,也不是很普遍。如果要将所有列读取为字符串,则可以使用以下构造,而无需关心列数。

from collections import defaultdict
import pandas as pd

pd.read_csv(file_or_buffer, converters=defaultdict(lambda i: str))

对于传递到的每个索引,将返回 。defaultdictstrconverters

评论

0赞 Sn3akyP3t3 1/16/2021
似乎没有提供任何影响。
0赞 sophros 1/16/2021
@Sn3akyP3t3:你怎么知道它不是针对受问题影响的版本?你怎么知道它不起作用 - 你得到的矛盾结果是什么?pandas
0赞 Codek 11/16/2021
我可以确认此示例仅适用于某些情况。我在本周早些时候应用了它,它确实有效。然而;然后我找到了另一个案例,应用了这个,它没有效果。(只有 3 列 df)我使用了此线程中也提到的“StringConverter”类选项,它运行良好。为什么?我不知道,但这就是发生的事情。
0赞 sophros 11/16/2021
@Codek:Python / pandas 的版本在运行之间有什么不同,还是只有不同的数据?
1赞 Codek 11/17/2021
好吧,实际上这是一个很好的观点,相同的解决方法不起作用的新项目可能是一个微妙的不同版本,明天检查一下!我当然很想了解这种怪异的原因!
22赞 julesl 5/2/2021 #5

如今,(pandas==1.0.5)它只是工作。

pd.read_csv(f, dtype=str)将所有内容读取为字符串,但 NAN 值除外。

以下是将解析为 NAN 的值列表:空字符串、'#N/A'、'#N/A N/A'、'#NA'、'-1.#IND'、'-1.#QNAN'、'-NaN'、'-nan'、 '1.#IND', '1.#QNAN', '', '不适用', '不适用', '不适用', '不适用', '不适用', 'nan', 'null'

如果您不希望此字符串被解析为 NAN,请使用na_filter=False

评论

0赞 Francisco Cortes 7/16/2022
小时+我自己的问题,然后让我找到这个!