如何使用数据条件填充 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 已优化以执行按列操作,而不是遍历行。您声明要执行以下操作:
- 计算给定品牌和型号的门的中位数。
- 用该中位数填充数据集中的空门值。
Pandas 中的第一步是 groupby
followed by a transform
:您正在查找 "group by" Maker
和 Model
,然后创建替换值对于 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
我有一个汽车数据集,必须训练一个模型来预测汽车的价格,但我的疑问在于数据清理。以下是数据框中存在的列 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 已优化以执行按列操作,而不是遍历行。您声明要执行以下操作:
- 计算给定品牌和型号的门的中位数。
- 用该中位数填充数据集中的空门值。
Pandas 中的第一步是 groupby
followed by a transform
:您正在查找 "group by" Maker
和 Model
,然后创建替换值对于 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