由this指导,我开始根据其dtype建立用于处理数据帧列的管道。但是在得到一些意外的输出和调试之后,我最终得到了测试数据帧和测试dtype检查:
# Creating test dataframe
test = pd.DataFrame({'bool' :[False, True], 'int':[-1,2],'float': [-2.5, 3.4],
'compl':np.array([1-1j, 5]),
'dt' :[pd.Timestamp('2013-01-02'), pd.Timestamp('2016-10-20')],
'td' :[pd.Timestamp('2012-03-02')- pd.Timestamp('2016-10-20'),
pd.Timestamp('2010-07-12')- pd.Timestamp('2000-11-10')],
'prd' :[pd.Period('2002-03','D'), pd.Period('2012-02-01', 'D')],
'intrv':pd.arrays.IntervalArray([pd.Interval(0, 0.1), pd.Interval(1, 5)]),
'str' :['s1', 's2'],
'cat' :[1, -1],
'obj' :[[1,2,3], [5435,35,-52,14]]
})
test['cat'] = test['cat'].astype('category')
test
test.dtypes
# Testing types
types = list(test.columns)
df_types = pd.DataFrame(np.zeros((len(types),len(types)), dtype=bool),
index = ['is_'+el for el in types],
columns = types)
for col in test.columns:
df_types.at['is_bool', col] = pd.api.types.is_bool_dtype(test[col])
df_types.at['is_int' , col] = pd.api.types.is_integer_dtype(test[col])
df_types.at['is_float',col] = pd.api.types.is_float_dtype(test[col])
df_types.at['is_compl',col] = pd.api.types.is_complex_dtype(test[col])
df_types.at['is_dt' , col] = pd.api.types.is_datetime64_dtype(test[col])
df_types.at['is_td' , col] = pd.api.types.is_timedelta64_dtype(test[col])
df_types.at['is_prd' , col] = pd.api.types.is_period_dtype(test[col])
df_types.at['is_intrv',col] = pd.api.types.is_interval_dtype(test[col])
df_types.at['is_str' , col] = pd.api.types.is_string_dtype(test[col])
df_types.at['is_cat' , col] = pd.api.types.is_categorical_dtype(test[col])
df_types.at['is_obj' , col] = pd.api.types.is_object_dtype(test[col])
# Styling func
def coloring(df):
clr_g = 'color : green'
clr_r = 'color : red'
mask = ~np.logical_xor(df.values, np.eye(df.shape[0], dtype=bool))
# OUTPUT
return pd.DataFrame(np.where(mask, clr_g, clr_r),
index = df.index,
columns = df.columns)
# OUTPUT colored
df_types.style.apply(coloring, axis=None)
bool bool
int int64
float float64
compl complex128
dt datetime64[ns]
td timedelta64[ns]
prd period[D]
intrv interval[float64]
str object
cat category
obj object
几乎一切都很好,但是此测试代码产生两个问题:
pd.api.types.is_string_dtype
会触发
在category
dtype上。这是为什么?是否应将其视为“预期”
行为? is_string_dtype
和is_object_dtype
会分别触发
其他?有点意外,因为即使在.dtypes
中,两种类型
被标记为object
,但最好有人澄清一下
一步一步。Ps:奖励问题-我认为熊猫在构建新版本时应该通过其内部测试时是正确的(例如测试代码中的df_types,但不带有“红色”,而是“记录有关错误的信息”) ?
答案 0 :(得分:1)
这归结为is_string_dtype
相当松散的支票,其中the implementation甚至有一个待办事项以使其更加严格,并链接到Issue #15585。
此检查不严格的原因是,pandas
中没有专用的字符串dtype,而是仅使用object
dtype存储了字符串,该字符串实际上可以存储任何内容。因此,更严格的检查可能会带来性能开销。
要回答您的问题:
这是由于CategoricalDtype.kind
被设置为'O'
的结果,这是is_string_dtype
进行的宽松检查之一。鉴于待办事项说明,这种情况将来可能会改变,所以这不是我要依靠的东西。
由于字符串存储为object
dtype,因此is_object_dtype
可以在字符串上触发,并且我认为这种行为是可靠的,因为实现几乎肯定不会改变不久的将来。由于对dtype.kind
中的is_string_dtype
的依赖,情况恰恰相反,与上述分类法有相同的警告。
是的,pandas
有一个测试套件,它将针对所创建的每个PR在各种CI服务上自动运行。该测试套件包括与您正在执行的检查类似的检查。
要添加的一个切线相关的注释:有一个名为fletcher
的库,该库使用Apache Arrow以与pandas
兼容的方式实现了更本地的字符串类型。它仍在开发中,目前可能不支持pandas
所做的所有字符串操作。