清理和填充数据科学分析的分类变量

Cleaning up & filling in categorical variables for Data Science analysis

我正在处理我的第一个机器学习问题,并且正在努力清理数据集中的分类特征。我的目标是建立一个攀岩推荐系统。

问题 1:

我有三列相关的列有错误信息:

现在的样子:

我希望它看起来像什么:

如果您按位置名称分组,则有不同的 location_id 号码和国家/地区与该名称相关联。但是,这些差异中的每一个都有明显的 winner/clear 多数。我有一个包含 200 万个条目的数据集,并且 location_id & location_country 的模式鉴于 location_name 压倒性地指向一个答案(例如:“300” & "USA" clear_creek).

使用 pandas/python,如何按 location_name 对我的数据集进行分组,根据该位置名称计算 location_id 和 location_country 的模式,然后替换整个 id & country 列与这些基于 location_name 的模式计算来清理我的数据?

我尝试过 groupby、replace、duplicated,但我认为最终我需要创建一个函数来执行此操作,老实说,我不知道从哪里开始。 (我提前为我的编码天真道歉)我知道必须有一个解决方案,我只需要指出正确的方向。

问题 2:

此外,有人对在我的 location_name 类别 (42,012/2 百万) 和 location_country(46,890/2 百万) 列中填写 NaN 值有建议吗?最好保留为未知值吗?我觉得根据频率填充这些特征会对我的数据集造成可怕的偏见。

data = {'index': [1,2,3,4,5,6,7,8,9], 
        'location_name': ['kalaymous', 'kalaymous', 'kalaymous', 'kalaymous',
                          'clear_creek', 'clear_creek', 'clear_creek', 
                          'clear_creek', 'clear_creek'],
        'location_id': [100,100,0,100,300,625,300,300,300], 
        'location_country': ['GRC', 'GRC', 'ESP', 'GRC', 'USA', 'IRE', 
                             'USA', 'USA', 'USA']}
df = pd.DataFrame.from_dict(data)

***正在寻找 return:

improved_data = {'index': [1,2,3,4,5,6,7,8,9], 
            'location_name': ['kalaymous', 'kalaymous', 'kalaymous', 'kalaymous',
                              'clear_creek', 'clear_creek', 'clear_creek', 
                              'clear_creek', 'clear_creek'],
            'location_id': [100,100,100,100,300,300,300,300,300], 
            'location_country': ['GRC', 'GRC', 'GRC', 'GRC', 'USA', 'USA', 
                                 'USA', 'USA', 'USA']}

new_df = pd.DataFrame.from_dict(improved_data)

正如 Erfan 提到的那样,了解您对第一个问题的预期输出会很有帮助。

第二个 pandas 有一个 fillna 方法。您可以使用此方法来填充 NaN 值。例如,要用 'UNKNOWN_LOCATION' 填充值,您可以执行以下操作:

df.fillna('UNKNOWN_LOCATION')

查看第一个问题的潜在解决方案:

df.groupby('location_name')[['location_id', 'location_country']].apply(lambda x: x.mode())

我们可以使用.agg in combination with pd.Series.mode and cast that back to your dataframe with map:

m1 = df.groupby('location_name')['location_id'].agg(pd.Series.mode)
m2 = df.groupby('location_name')['location_country'].agg(pd.Series.mode)

df['location_id'] = df['location_name'].map(m1)
df['location_country'] = df['location_name'].map(m2)

print(df)
   index location_name  location_id location_country
0      1     kalaymous          100              GRC
1      2     kalaymous          100              GRC
2      3     kalaymous          100              GRC
3      4     kalaymous          100              GRC
4      5   clear_creek          300              USA
5      6   clear_creek          300              USA
6      7   clear_creek          300              USA
7      8   clear_creek          300              USA
8      9   clear_creek          300              USA

您可以通过使用df.iat[]计算模式来使用transform:

df=(df[['location_name']].join(df.groupby('location_name').transform(lambda x: x.mode()
                                                   .iat[0])).reindex(df.columns,axis=1))
print(df)

  index location_name location_id location_country
0     1     kalaymous         100              GRC
1     1     kalaymous         100              GRC
2     1     kalaymous         100              GRC
3     1     kalaymous         100              GRC
4     5   clear_creek         300              USA
5     5   clear_creek         300              USA
6     5   clear_creek         300              USA
7     5   clear_creek         300              USA
8     5   clear_creek         300              USA