python - 在 pandas DataFrame 中检查 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
几乎一切都很好,但是这个测试代码产生了两个问题:
- 这里最奇怪的是在dtype上
pd.api.types.is_string_dtype
触发。category
这是为什么?是否应该将其视为“预期”行为? - 为什么
is_string_dtype
和is_object_dtype
对方开火?这有点出乎意料,因为即使在.dtypes
这两种类型中都被标记为object
,但如果有人逐步澄清它会更好。
Ps:额外的问题 - 当我认为 pandas 在构建新版本时应该通过其内部测试时我是对的吗(比如测试代码中的 df_types,但不是用“红色着色”而是“记录错误信息”)?
编辑:熊猫版0.24.2
。
解决方案
这归结为is_string_dtype
一个相当松散的检查,实现甚至有一个 TODO 注释以使其更加严格,链接到Issue #15585。
这个检查不严格的原因是因为没有一个专用的字符串 dtype pandas
,而是字符串只是用object
dtype 存储的,它可以真正存储任何东西。因此,更严格的检查可能会引入性能开销。
要回答您的问题:
这是
CategoricalDtype.kind
设置为 的结果'O'
,这是松散的检查之一is_string_dtype
。鉴于 TODO 注释,这可能会在未来发生变化,所以这不是我所依赖的。由于字符串存储为
object
dtype,因此触发字符串是有意义的is_object_dtype
,我认为这种行为是可靠的,因为实现几乎肯定不会在不久的将来发生变化。dtype.kind
由于对in的依赖,反之亦然is_string_dtype
,它与上述分类具有相同的警告。是的,
pandas
有一个测试套件将自动在各种 CI 服务上为每个创建的 PR 运行。测试套件包括与您正在做的类似的检查。
一个切线相关的注释要添加:有一个名为的库fletcher
,它使用 Apache Arrow 以兼容的方式实现更原生的字符串类型pandas
。它仍在开发中,目前可能不支持所有的字符串操作pandas
。
推荐阅读
- windows - 在 Windows 10 的自动启动中以不同用户身份启动软件
- virtualbox - 无法启动 Genymotion 虚拟设备,AMD 处理器中的 CPU 不兼容
- php - 使用扩展模型中的关系时将返回什么模型?
- git - Git:如何重新定位到过去的特定提交?
- react-native - 键盘可见性永久显示在屏幕上
- python - 如何捕获线程中发生的异常?
- python - 如何使用第一个解决方案策略作为本地搜索元启发式的初始解决方案?
- windows - 如何使用 power-shell 将登录下的用户列为服务本地安全策略
- ios - React Native IOS Archive 不适用于 React Native 新版本
- powershell - 缺少 PowerShell 类方法描述