Python 检测pandas.DataFrame中的列是否为分类列的好方法是什么?
我一直在开发一个自动预处理pandas.DataFrame格式数据的工具。在这个预处理步骤中,我希望以不同的方式处理连续数据和分类数据。特别是,我希望能够将OneHotEncoder应用于分类数据 现在,假设我们提供了pandas.DataFrame,并且没有关于DataFrame中数据的其他信息。确定pandas.DataFrame中的列是否为分类列时,使用什么好的启发式方法 我最初的想法是: 1) 如果列中有字符串(例如,列数据类型为Python 检测pandas.DataFrame中的列是否为分类列的好方法是什么?,python,pandas,scikit-learn,Python,Pandas,Scikit Learn,我一直在开发一个自动预处理pandas.DataFrame格式数据的工具。在这个预处理步骤中,我希望以不同的方式处理连续数据和分类数据。特别是,我希望能够将OneHotEncoder应用于分类数据 现在,假设我们提供了pandas.DataFrame,并且没有关于DataFrame中数据的其他信息。确定pandas.DataFrame中的列是否为分类列时,使用什么好的启发式方法 我最初的想法是: 1) 如果列中有字符串(例如,列数据类型为object),则该列很可能包含分类数据 2) 如果列中某
object
),则该列很可能包含分类数据
2) 如果列中某些百分比的值是唯一的(例如>=20%),则该列很可能包含连续数据
我发现1)
效果很好,但2)
效果不太好。我需要更好的启发法。你将如何解决这个问题
编辑:有人要求我解释为什么
2)
效果不好。在一些测试案例中,我们在一列中仍然有连续的值,但在该列中没有许多唯一的值。在这种情况下,2)
中的启发式显然失败了。还有一个问题是,我们有一个分类列,其中有许多、许多唯一的值,例如,泰坦尼克号数据集中的乘客姓名。同样的列类型错误分类问题。在相反的策略中,识别类别更好,因为它取决于数据的内容。从技术上讲,地址数据可以被认为是无序的分类数据,但通常我不会这样使用它
对于调查数据,一个想法是寻找Likert量表,例如5-8个值,字符串(可能需要硬编码(和翻译)级别以查找“好”、“坏”、“同意”、“非常。*”或0-8范围+NA的int值
国家和类似的事物也可能是可识别的
年龄组(“.-”)也可能起作用。以下是几种方法:
方法1)通常比方法2)更适合我。但是,如果存在“长尾分布”,则方法2)更好,其中少量分类变量具有高频率,而大量分类变量具有低频率。在许多地方,您可以“窃取”可转换为“数字”的格式定义。##e-#就是这样一种格式,只是为了举例说明。也许你能找到一个图书馆这样做。
我试着先把所有的东西都转换成数字,剩下的是什么,好吧,除了保持它们的分类之外,没有其他办法了。我认为这里真正的问题是,你是想偶尔打扰用户一次,还是偶尔默默地失败一次 如果你不介意打扰用户,也许检测歧义并提出错误是最好的方法 如果你不介意默默地失败,那么你的启发式就可以了。我认为你不会找到比这更好的东西。如果你真的想,我想你可以把这变成一个学习问题。下载一组数据集,假设它们是世界上所有数据集的一个整体,并根据每个数据集/列的特征进行训练,以预测分类与连续
当然,最终没有什么是完美的。例如,列(1, 8, 22,8, 9, 8)指的是一天中的几个小时还是狗的品种? < P>我一直在思考一个类似的问题,而且我认为它似乎是一个分类问题,它可以从一个模型中受益。p> 我敢打赌,如果您检查了一组数据集,并为每列/每只熊猫提取了这些特征。系列:
- %浮动:浮动值的百分比
- %int:为整数的值的百分比
- %字符串:为字符串的值的百分比
- %唯一字符串:唯一字符串值的数目/总数
- %唯一整数:唯一整数值的数目/总数
- 平均数值(非数值视为0)
- 数值的标准偏差
有一个相关的问题很有趣:给定一组列,您能否判断它们是否已经是一个热编码的列?例如,在森林覆盖类型预测kaggle竞赛中,您将自动知道土壤类型是一个单一的分类变量。您可以定义哪些数据类型算作数字,然后排除相应的变量 如果初始数据帧为df:
numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
dataframe = df.select_dtypes(exclude=numerics)
我一直在看这个,觉得分享我所拥有的可能有用。这建立在@Rishabh Srivastava答案的基础上
import pandas as pd
def remove_cat_features(X, method='fraction_unique', cat_cols=None, min_fraction_unique=0.05):
"""Removes categorical features using a given method.
X: pd.DataFrame, dataframe to remove categorical features from."""
if method=='fraction_unique':
unique_fraction = X.apply(lambda col: len(pd.unique(col))/len(col))
reduced_X = X.loc[:, unique_fraction>min_fraction_unique]
if method=='named_columns':
non_cat_cols = [col not in cat_cols for col in X.columns]
reduced_X = X.loc[:, non_cat_cols]
return reduced_X
然后,您可以调用此函数,给出一个名称为
X
,您可以删除命名的分类列,也可以选择删除具有少量唯一值的列(由min\u fraction\u unique
指定)。我相信这个问题几乎完全没有定义。世界上所有数据集的分布情况如何?例如,对于邮政服务或电话簿,你的规则1失败得很惨。试着区分数字数据和分类数据。@Barmaley。
numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
dataframe = df.select_dtypes(exclude=numerics)
import pandas as pd
def remove_cat_features(X, method='fraction_unique', cat_cols=None, min_fraction_unique=0.05):
"""Removes categorical features using a given method.
X: pd.DataFrame, dataframe to remove categorical features from."""
if method=='fraction_unique':
unique_fraction = X.apply(lambda col: len(pd.unique(col))/len(col))
reduced_X = X.loc[:, unique_fraction>min_fraction_unique]
if method=='named_columns':
non_cat_cols = [col not in cat_cols for col in X.columns]
reduced_X = X.loc[:, non_cat_cols]
return reduced_X