【问题标题】:What is the proper way to identify the data type of columns in a pandas dataframe?识别熊猫数据框中列的数据类型的正确方法是什么?
【发布时间】:2021-03-16 21:35:39
【问题描述】:

我目前正在开展一个项目,我需要将 pandas 数据框中的数据转换为使用不同(非 python)类型系统的另一种表示形式。 pandas 的serialization/io methods 之一没有涵盖转换。特别是我需要将 pandas 数据框列数据类型映射到其他类型系统的数据类型。对于初学者,我们假设目标类型系统非常简单,只有 stringintegerfloatbooleantimestamp 类型。

所以,我首先通过一个简单的示例查看dataframe dtypes

import pandas as pd
from datetime import datetime

headers = ["string", "integer", "float", "boolean", "timestamp"]
data = [["a", 1, 1.0, True, datetime.now()]]

df = pd.DataFrame(data, columns=headers)
dts = df.dtypes

for col in dts.index:
  print("column: ", col, " - type: ", dts[col].name)

这给了我:

column:  string  - type:  object
column:  integer  - type:  int64
column:  float  - type:  float64
column:  boolean  - type:  bool
column:  timestamp  - type:  datetime64[ns]

好的,为字符串列获取object 并不好,所以我找到了Dataframe.convert_dtypes() 方法,当它添加到数据框创建行时给了我:

column:  string  - type:  string
column:  integer  - type:  Int64
column:  float  - type:  Int64
column:  boolean  - type:  boolean
column:  timestamp  - type:  datetime64[ns]

更适合我的字符串列,但现在我的整数列和浮点列 (!) 和 boolean 都得到了 Int64(带有大写“I”),而不是 bool。 (好的,当我在示例数据中使用诸如“0.1”之类的“真实”浮点数时,我回到float64,但仍然......)

这让我想知道我是否在正确的轨道上使用这种方法。然后我查看了numpy dtype documentationnumpy dtype charcodes。但是似乎没有针对每种可能的数据类型的字符码,尤其是。不适用于字符串类型。此外,我在应用 convert_dtypes() 后获得的 pandas 扩展 dtype 不再具有 char 属性。

所以我的问题是,获取可用于将这些数据类型映射到另一个类型系统的 pandas 数据框中的列的数据类型标识符的规范方法是什么?

【问题讨论】:

    标签: python pandas dataframe types


    【解决方案1】:

    df.dtypes获取数据类型标识符的规范方式。您可以使用<dtype>.str 为每个dtype 打印相关的底层numpy dtype 代码。您还可以使用<dtype>.kind 获取类型(整数、浮点数...):

    import pandas as pd
    from datetime import datetime
    
    headers = ["string", "integer", "float", "boolean", "timestamp"]
    data = [["a", 1, 1.0, True, datetime.now()]]
    
    df = pd.DataFrame(data, columns=headers)
    
    dts = df.dtypes
    for index, value in dts.items():
        print("column %s dtype[class: %s; name: %s; code: %s; kind: %s]" % (index, type(value), value.name, value.str, value.kind))
    

    产量:

    column string dtype[class: <class 'numpy.dtype'>; name: object; code: |O; kind: O]
    column integer dtype[class: <class 'numpy.dtype'>; name: int64; code: <i8; kind: i]
    column float dtype[class: <class 'numpy.dtype'>; name: float64; code: <f8; kind: f]
    column boolean dtype[class: <class 'numpy.dtype'>; name: bool; code: |b1; kind: b]
    column timestamp dtype[class: <class 'numpy.dtype'>; name: datetime64[ns]; code: <M8[ns]; kind: M]
    

    问题是,如您所述,某些数据类型是在 pandas 中专门定义的,但它们由 numpy 数据类型支持(它们具有 numpy 数据类型代码)。例如,numpy 定义了您可以在上面看到的 datetime64[ns],但 pandas 在其之上定义了 timezone-localized dtype。你可以看到它:

    # localize with timezone
    df['timestamp'] = pd.DatetimeIndex(df['timestamp']).tz_localize(tz='UTC')
    
    # look at the dtype of timestamp: now a pandas dtype
    index, value = 'timestamp', df.dtypes.timestamp
    print("column %s dtype[class: %s; name: %s; code: %s; kind: %s]" % (index, type(value), value.name, value.str, value.kind))
    

    产量

    column timestamp dtype[class: <class 'pandas.core.dtypes.dtypes.DatetimeTZDtype'>; name: datetime64[ns, UTC]; code: |M8[ns]; kind: M]    
    

    现在 dtype class 是一个自定义的 pandas 类 (DatetimeTZDtype),而底层的 dtype 代码是一个 numpy 的。如果您使用 string 数据类型,默认情况下不在 numpy 中的数据类型也是如此。

    总而言之,要达到最初的目标,您应该首先查看type(&lt;dtype&gt;),如果它不是自定义的pandas,则查看numpy &lt;dtype&gt;.kind(最好是@987654336 @as numpy 允许您定义 许多 种整数(大/小端序、nb 位等)。

    最后如你所见,Dataframe.convert_dtypes() 是一个转换器,它有参数可以选择打开/关闭哪个自动转换功能。

    【讨论】:

    • 感谢@smarie,提供详尽的回答!我想我会选择&lt;dtype&gt;.kind。只是关于字符串的后续问题:对于那些我很友善的O(对于日期和时间列也是如此,例如date.today()time(17,5,31))。如何安全地识别字符串列并将它们与日期和时间列分开(在我假设的简单目标类型系统中,它们应该映射到 timestamp 类型)。看来我确实需要为此申请convert_dtypes()
    • 正如我在帖子中提到的(为了清楚起见,我编辑了最后几位),您应该首先阅读type(&lt;dtype&gt;)以确定这是否是熊猫类型(字符串等.) 然后然后查看&lt;dtype&gt;.kind。您是对的,能够推断某些对象是字符串 dtype,您应该尝试convert_dtypes()。我希望有一天 pandas 也会提供你提到的日期和时间这样的东西。
    猜你喜欢
    • 2020-09-06
    • 2013-12-24
    • 1970-01-01
    • 1970-01-01
    • 2022-10-08
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多