pandas 字符串与范畴数据类型的奇怪行为

nhaq1z21  于 2023-02-14  发布在  其他
关注(0)|答案(1)|浏览(108)

我遇到了一个非常奇怪的问题,或者我可以说是一个bug,当处理一些类别与字符串Dtype时。看看这个简单的示例 Dataframe :

import pandas as pd
import numpy as np
data = pd.DataFrame({
    'status' :  ['pending', 'pending','pending', 'canceled','canceled','canceled', 'confirmed', 'confirmed','confirmed'],
    'partner' :  ['A', np.nan,'C', 'A',np.nan,'C', 'A', np.nan,'C'],
    'product' : ['afiliates', 'pre-paid', 'giftcard','afiliates', 'pre-paid', 'giftcard','afiliates', 'pre-paid', 'giftcard'],
    'brand' : ['brand_1', 'brand_2', 'brand_3','brand_1', 'brand_2', 'brand_3','brand_1', 'brand_2', 'brand_3'],
    'gmv' : [100,100,100,100,100,100,100,100,100]})

data = data.astype({'partner':'category','status':'category','product':'category', 'brand':'category'})

执行单个位置选择时

test = data.loc[(data.partner !='A') | ((data.brand == 'A') & (data.status == 'confirmed'))]

这是输出

现在,只需将我的分类列移到string(我将它移回string,因为有一个与groupby有关的问题,如here所述)

data = data.astype({'partner':'string','status':'string','product':'string', 'brand':'string'})

以免发出同样的锁定命令。

test2 = data.loc[(data.partner !='A') | ((data.brand == 'A') & (data.status == 'confirmed'))]

但是看看输出!

我真的不知道为什么它不起作用。我已经弄清楚了这是与被送回字符串的NAN范畴有关的东西,但我不明白为什么这会是一个问题。

vlurs2pr

vlurs2pr1#

问题恰恰在于类别类型和字符串类型中的NAN值之间的差异:
对于category,nan值的类型是'float'(作为典型的nan),您可以在比较中使用它,因此:data.partner !='A'对于所有具有NaN的行都将为True。
当类型转换为字符串时,nan值的类型转换为panda._libs.missing.NAType,您不能在比较中使用此类型,因此现在:data.partner !='A'返回非True的值,并且结果不同。
基本上,类别类型中的NaN本身不是一个类别,所以它的处理方式不同。这就是为什么你不能在类别上使用fillna,你必须为它定义一个类别值。你可以使用如下代码:

data['partner'] = data.partner.cat.add_categories('Not_available').fillna('Not_available')

添加一个自定义的NA类别并替换丢失的值。现在,如果转换为字符串并运行相同的条件,您应该会得到相同的结果。

相关问题