【问题标题】:Retain None in pandas DataFrame (in spite of astype() and to_parquet())在 pandas DataFrame 中保留 None (尽管有 astype() 和 to_parquet())
【发布时间】:2020-04-28 18:29:17
【问题描述】:

如何强制 pandas DataFrame 保留 None 值,即使在使用 astype() 时也是如此?

详情

由于pd.DataFrame 构造函数没有提供复合dtype 参数,我使用以下函数修复类型(to_parquet() 所需):

def _typed_dataframe(data: list) -> pd.DataFrame:
    typing = {
        'name': str,
        'value': np.float64,
        'info': str,
        'scale': np.int8,
    }    
    result = pd.DataFrame(data)
    for label in result.keys():
        result[label] = result[label].astype(typing[label])
    return result

不幸的是,result[info] = result[info].astype(str)info 中的所有None 值转换为"None" 字符串。我怎样才能禁止这种情况,即保留 None 值?

更准确地说:data 中的None 值在result DataFrame 中变为np.nan,由astype(str) 变为"nan",当从result 中提取时变为"None"

【问题讨论】:

  • 假设您使用的是 pandas-1.0,您可以使用 string 数据类型而不是 str 数据类型。它要做的是将所有 NaN 值保留为可空整数类型<NA>。所以它会像:result[info] = result[info].astype("string")
  • @frosty:有趣,我不知道 pandas 有一个数据类型 string (+1)。对应的 Parquet 格式会与str 的格式兼容吗?这是 Parquet 消费者对 info 的期望。如果是这样,这是一个非常简单的解决方案,值得作为答案!
  • 在拼花格式方面我不是很专家,但我尝试在将类型转换为StringDType/string 并在 Jupyter 笔记本中读取相同文件时使用熊猫编写该拼花,我的笔记本内核死了很奇怪。但是要检查它是否将其读取为字符串,我在 pyspark 中读取它并检查了它的架构,是的,它保留了空值,并且强制转换列的格式为string。我仍然需要弄清楚为什么内核在 pandas 中读取 parquet 时不断死亡,也许你可以尝试在最后运行一次。

标签: python pandas types null parquet


【解决方案1】:

根据@frosty 的评论,我们可以使用替代方法

    typing = {
        'name': str,
        'value': np.float64,
        'info': pd.StringDtype(),
        'scale': np.int8,
    }    

但是,这需要pandas ~= 1.0.0


作为更好的解决方案,您可以替换

for label in result.keys():
    result[label] = result[label].astype(typing[label])

通过

result.astype(schema)

不幸的是,result.astype(typing) 无效,因为它无法处理复合类型。

【讨论】:

    猜你喜欢
    • 2022-07-28
    • 2013-03-17
    • 2021-12-16
    • 2016-03-02
    • 2013-09-08
    • 1970-01-01
    • 2013-06-10
    • 2017-08-06
    相关资源
    最近更新 更多