Pandas 将 csv 读取为字符串类型

Posted

技术标签:

【中文标题】Pandas 将 csv 读取为字符串类型【英文标题】:Pandas reading csv as string type 【发布时间】:2013-06-04 00:31:30 【问题描述】:

我有一个带有字母数字键的数据框,我想将其保存为 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  (  <

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

【问题讨论】:

如果您能说出为什么要将其保存为字符串的“各种原因”,那就太好了。上下文可能有助于找到更优雅的解决方案。 这能回答你的问题吗? Import pandas dataframe column as string not int 【参考方案1】:

更新:这有 been fixed:从 0.11.1 开始,您通过 str/np.str 将等同于使用 object

使用对象数据类型:

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

或者更好,只是不要指定数据类型:

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

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

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,例如见here。

【讨论】:

我认为read_csv 应该 a) 引发无效传递的 dtype,b) 只需将 str dtype 转换为 object,打开一个问题? 谢谢,我会试试的。我已经提到我不能在不指定类型的情况下直接读入它,Pandas 不断采用数字键,我需要将它们作为字符串并将它们解析为浮点数。就像我在示例中所说的那样:1234E5 被视为:1234.0x10^5,当我去查找它时,这对我没有任何帮助。 @daver 这在 0.11.1 发布时已修复(很快)。谢谢! 仅仅包括dtype=object(而不是index_col)就解决了我所有前导零消失的问题。 设置dtype 是不够的。例如,df.applymap(lambda x: x.strip()) 会抛出错误 AttributeError: ("'float' object has no attribute 'strip'", 'occurred at index A'),因为 pandas 在途中将object 强制转换为float【参考方案2】:

就像 Anton T 在他的评论中所说,pandas 会使用其类型嗅探器随机将 object 类型转换为 float 类型,即使您传递了 dtype=objectdtype=strdtype=np.str

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

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

如果你不知道你会读多少列,你甚至可以通过range(0, N) 传递比列数大得多的 N。

【讨论】:

我在版本 '0.25.3' 中得到“IndexError: list index out of range”【参考方案3】:

现在,(pandas==1.0.5) 它可以正常工作。

pd.read_csv(f, dtype=str) 会将除 NAN 值之外的所有内容都读取为字符串(empty string, ‘#N/A’, ‘#N/A N/A’, ‘#NA’, ‘-1.#IND’, ‘-1.#QNAN’, ‘-NaN’, ‘-nan’, ‘1.#IND’, ‘1.#QNAN’, ‘’, ‘N/A’, ‘NA’, ‘NULL’, ‘NaN’, ‘n/a’, ‘nan’, ‘null’,如果您不希望将此字符串解析为 NAN,请使用 na_filter=False

【讨论】:

【参考方案4】:

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

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())

【讨论】:

【参考方案5】:

上述许多答案都很好,但既不优雅也不通用。如果您想将所有列作为字符串读取,您可以使用以下构造而无需关心列数。

from collections import defaultdict
import pandas as pd

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

defaultdict 将为传入converters 的每个索引返回str

【讨论】:

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

以上是关于Pandas 将 csv 读取为字符串类型的主要内容,如果未能解决你的问题,请参考以下文章

pandas使用read_csv函数读取文件时指定数据列的数据类型pandas使用read_csv函数读取文件时通过keep_default_na参数设置缺失值替换为空字符串

pandas使用read_csv读取文件数据设置converters参数将百分比字符串转换为数字

将列表写入 pandas 数据帧到 csv,从 csv 读取数据帧并再次转换为列表而无需字符串

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

将 csv 文件作为浮点数读取到 pandas 数据帧

python pandas中如何将dataframe中的一列字符串类型转换为浮点类型?