【问题标题】:pandas: read_csv how to force bool data to dtype bool instead of objectpandas:read_csv 如何强制 bool 数据为 dtype bool 而不是 object
【发布时间】:2021-10-18 17:45:16
【问题描述】:

我正在阅读一个大型平面文件,其中包含多列时间戳数据。数据有一个布尔列,可以是 True/False 或没有条目(计算结果为 nan)。

读取 csv 时,bool 列被类型转换为对象,这会因为序列化错误而阻止将数据保存在 hdfstore 中。

示例数据:

A    B    C    D
a    1    2    true
b    5    7    false
c    3    2    true
d    9    4

我使用如下命令读取

import pandas as pd
pd.read_csv('data.csv', parse_dates=True)

一种解决方案是在读取 csv 时指定 dtype,但我希望有一个更简洁的解决方案,例如 convert_objects,我可以在其中指定 parse_numeric 或 parse_dates。

【问题讨论】:

  • 你的最后一行有一个缺失值,这会产生一个混合的dtype,你应该发现前3行实际上是boolean dtype,你想对缺失的值做什么?
  • 这正是我的问题。前三个实际上是布尔值。 D 列的数据稀疏。我可以使用默认值 false。
  • 然后调用 df['D'] = df['D'].fillna(False) 将确保该列的 dtype 是同质的
  • fillna 是否采用 dict 可以将不同的默认值呈现给不同的列?这将解决我的用例,因为我所呈现的只是数据的一个子集。很抱歉,我无法从documentation
  • 哈哈我误读了这个问题,以为是要求将文件的列转换为np.bool

标签: python pandas


【解决方案1】:

由于您的 csv 中有一个缺失值,因此列的 dtype 显示为对象,因为您有混合 dtypes,前 3 行值是布尔值,最后一个值是浮点数。

要转换 NaN 值使用 fillna,它接受一个 dict 以将所需的填充值映射到列并生成同质 dtype:

>>> t = """
A   B   C    D
a   1  NaN  true
b   5   7   false
c   3   2   true
d   9   4 """
>>> df = pd.read_csv(io.StringIO(t),sep='\s+')
>>> df
   A  B   C    D
0  a  1  NaN  True
1  b  5   7   False
2  c  3   2   True
3  d  9   4   NaN
>>> df.fillna({'C':0, 'D':False})
   A  B  C   D
0  a  1  0  True
1  b  5  7  False
2  c  3  2  True
3  d  9  4  False

【讨论】:

  • 更精确地按列 +1 映射 fillna()
【解决方案2】:

您可以使用dtype,它接受用于映射列的字典:

dtype : Type name or dict of column -> type
    Data type for data or columns. E.g. {'a': np.float64, 'b': np.int32}
import pandas as pd
import numpy as np
import io

# using your sample
csv_file = io.BytesIO('''
A    B    C    D
a    1    2    true
b    5    7    false
c    3    2    true
d    9    4''')

df = pd.read_csv(csv_file, sep=r'\s+', dtype={'D': np.bool})
# then fillna to convert NaN to False
df = df.fillna(value=False)

df 
   A  B  C      D
0  a  1  2   True
1  b  5  7  False
2  c  3  2   True
3  d  9  4  False

df.D.dtypes
dtype('bool')

【讨论】:

    【解决方案3】:

    从这个very similar question,我建议使用converters kwarg:

    import pandas as pd
    pd.read_csv('data.csv',
                converters={'D': lambda x: True if x == 'true' else False})
    

    根据您的评论指出 NaN 值应替换为 False。

    converters 关键字参数可以采用字典,其中键是列名,值是要应用的函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-25
      • 1970-01-01
      相关资源
      最近更新 更多