如何使用数据条件填充 pandas 数据框中的缺失值?

How can I fill in missing values in pandas dataframe using conditions on the data?

我有一个汽车数据集,必须训练一个模型来预测汽车的价格,但我的疑问在于数据清理。以下是数据框中存在的列 car_df:

Data columns (total 17 columns):
Id                     53515 non-null int64
Maker                  53515 non-null object
model                  53515 non-null object
Location               53515 non-null object
Distance               52304 non-null float64
Owner Type             53515 non-null object
manufacture_year       53515 non-null int64
Age of car             53515 non-null int64
engine_displacement    53515 non-null int64
engine_power           52076 non-null float64
body_type              4136 non-null object
Vroom Audit Rating     53515 non-null int64
transmission           53515 non-null object
door_count             53515 non-null object
seat_count             53515 non-null object
fuel_type              53515 non-null object
Price                  53515 non-null float64
dtypes: float64(3), int64(5), object(9)

列 door_count 和 seat_count 包含我想用数值替换的术语 'None'。我的算法: 如果对于特定的制造商,模型组合 door_count 是 'None',则用制造商,模型组合的 door_count 的中值填充它。 例如,如果 Maker 是 Skoda,型号是 Octavia,则算法会找到 door_count 的中位数并填充 none 值。

这是我尝试实现的代码片段:

def find_door_count(Maker, model):
    car_df_temp = car_df[car_df['door_count']!='None']
    car_df_temp['door_count'] = car_df_temp['door_count'].astype('int64')
    ans = car_df_temp[(car_df_temp['Maker']==Maker) & (car_df_temp['model']==model)]['door_count'].median()
    return ans

car_df['door_count'].apply(lambda row: find_door_count(row['Maker'], row['model']))

在 运行 上面的代码片段中,我收到以下错误:

----> 1 car_df['door_count'].apply(lambda 行:find_door_count(row['Maker'], row['model']))

类型错误:字符串索引必须是整数

你能告诉我哪里错了吗?

这就是错误所说的

data[1]  #this will work 
data['string'] #this will not work

因为您 select car_df 中的列 door_count 带有语句 car_df['door_count'],您的代码正在调用 Series.apply。传递给此方法的函数采用表示 DataFrame 列的 Series 或单个值,而不是您可能认为的 DataFrame 行。

我建议你重新考虑一下你想如何解决这个问题。 Pandas 已优化以执行按列操作,而不是遍历行。您声明要执行以下操作:

  1. 计算给定品牌和型号的门的中位数。
  2. 用该中位数填充数据集中的空门值。

Pandas 中的第一步是 groupby followed by a transform:您正在查找 "group by" MakerModel,然后创建替换值对于 door_count,这是这些组中该列的 "transformation"。假设 'door_count' 的值是 float 类型,代码如下所示:

car_df['median_door_counts'] = car_df.groupby(['Maker', 'Model'])['door_count'].transform('median')  # perform the transformation

这是一个实际的例子:

import pandas as pd
import numpy as np

car_df = pd.DataFrame({"Maker": ["Ford", "Tesla", "GM"] * 4,
                       "Model": ["Pinto", "S", "Sierra", "Fiesta", "X", "Volt"] * 2, 
                       "door_count": np.random.randint(0, 4, size=12, dtype="float")})

car_df['door_count'] = car_df['door_count'].astype(float)     # allow door_count to be nan
car_df.loc[car_df['door_count'] == 0, 'door_count'] = np.nan  # generate some nans

car_df['median_door_counts'] = car_df.groupby(['Maker', 'Model'])['door_count'].transform('median')
print(car_df)
#     Maker   Model  door_count  median_door_counts
# 0    Ford   Pinto         NaN                 NaN
# 1   Tesla       S         2.0                 2.0
# 2      GM  Sierra         2.0                 2.0
# 3    Ford  Fiesta         2.0                 2.0
# 4   Tesla       X         2.0                 2.5
# 5      GM    Volt         1.0                 1.0
# 6    Ford   Pinto         NaN                 NaN
# 7   Tesla       S         NaN                 2.0
# 8      GM  Sierra         NaN                 2.0
# 9    Ford  Fiesta         2.0                 2.0
# 10  Tesla       X         3.0                 2.5
# 11     GM    Volt         1.0                 1.0

您应该查找 Series.median 并检查默认参数,以了解其工作原理以及我将列转换为浮点值的原因。另请注意,福特 Pinto 缺少 door_count 的所有值,因此它们的中值也缺失。

现在这些中位数是 DataFrame 中的一列,因此您可以使用 selection 逻辑执行您认为合适的替换操作:

null_door = car_df['door_count'].isnull()  # or whatever logic you want
car_df.loc[null_door, 'door_count'] = car_df.loc[null_door, 'median_door_counts']

我生成的示例数据的结果:

print(car_df)
#     Maker   Model  door_count  median_door_counts
# 0    Ford   Pinto         NaN                 NaN
# 1   Tesla       S         2.0                 2.0
# 2      GM  Sierra         2.0                 2.0
# 3    Ford  Fiesta         2.0                 2.0
# 4   Tesla       X         2.0                 2.5
# 5      GM    Volt         1.0                 1.0
# 6    Ford   Pinto         NaN                 NaN
# 7   Tesla       S         2.0                 2.0
# 8      GM  Sierra         2.0                 2.0
# 9    Ford  Fiesta         2.0                 2.0
# 10  Tesla       X         3.0                 2.5
# 11     GM    Volt         1.0                 1.0