QST:在pandas dataframe中,将string[pyarrow]类型的列转换为boolean的规范方法是什么?

2uluyalo  于 2023-06-20  发布在  其他
关注(0)|答案(2)|浏览(168)

我想转换字符串数据,这确实是布尔值(或空值)。值是y/n/NA,或真/假/NA,或甚至这些的混合。
当使用pandas,默认为numpy后端时,从字符串数据到boolean数据的转换可以顺利进行:

import pandas as pd

df = pd.DataFrame({"col1": ["true", None, "false"]})
assert df.dtypes["col1"] == "object", df.dtypes["col1"]
# convert to boolean
df["col1"] = df["col1"].replace({'true': True, 'false': False}).astype(bool)
assert df.dtypes["col1"] == bool, df.dtypes["col1"]

然而,当使用pyarrow后端时(在我的用例中,我实际上使用了pd.read_parquetdtype_backend-但我在下面的示例中显式设置了类型):

df_pyarrow = pd.DataFrame(
    {"col1": ["true", None, "false"]}, dtype="string[pyarrow]"
)
assert df_pyarrow.dtypes["col1"] == "string", df_pyarrow.dtypes["col1"]
df_pyarrow["col1"] = (
    df_pyarrow["col1"]
    .replace({'true': True, 'false': False})  # fails at this step
    .astype(bool)
)
assert df_pyarrow.dtypes["col1"] == "bool[pyarrow]", df_pyarrow.dtypes["col1"]

但是这在. replace()失败了,因为pyarrow抱怨了,这是正确的!,TrueFalse不是字符串[pyarrow]的有效值:TypeError: Scalar must be NA or str
我发现这个方法是有效的:

df_pyarrow["col1"] = df_pyarrow["col1"] == "true"

assert df_pyarrow.dtypes["col1"] == "bool[pyarrow]", df_pyarrow.dtypes["col1"]

不过:

  • df_pyarrow.info()仍然显示col1string[pyarrow]
  • 这个方法不是很灵活:如果True/False有多个值会怎么样

在pandas dataframe中,将string[pyarrow]类型的列转换为boolean的规范方法是什么?

1tuwyuhd

1tuwyuhd1#

你应该使用map而不是replace

df_pyarrow["col1"] = (
    df_pyarrow["col1"]
    .map({'true': True, 'false': False})
    .astype("bool[pyarrow]")
)

它适用于numpy,因为numpy中的字符串数组实际上是对象数组。所以你可以用布尔值替换字符串,它们仍然是对象。
使用pandas和pyarrow后端,它对类型更加严格。

wtzytmuj

wtzytmuj2#

如果我用途:

df = (pd.read_parquet('data.parquet', dtype_backend='pyarrow')
        .astype({'col1': 'bool[pyarrow]'}))

我得到:

>>> df
    col1
0   True
1   <NA>
2  False

>>> df.dtypes
col1    bool[pyarrow]
dtype: object

>>> df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 1 columns):
 #   Column  Non-Null Count  Dtype        
---  ------  --------------  -----        
 0   col1    2 non-null      bool[pyarrow]
dtypes: bool[pyarrow](1)
memory usage: 130.0 bytes

最小可重现示例:

df = pd.DataFrame({'col1': ['true', None, 'false']})
df.to_parquet('data.parquet', engine='pyarrow')

相关问题