Python 如何根据与值的辅助数据框匹配的条件在主数据框的列中填充NAN,以使用多个填充值填充NAN
我需要根据由Python 如何根据与值的辅助数据框匹配的条件在主数据框的列中填充NAN,以使用多个填充值填充NAN,python,pandas,nan,Python,Pandas,Nan,我需要根据由groupby和mean函数创建的第二个数据帧,在我的主数据帧中填充NA值。我的原始数据帧有大约1.5K个NAN需要填充,因此这需要在大规模复制。我创建了一个假数据框,它是使用假场景对我的数据进行的一个简短、快速、肮脏的模仿。我不能和你分享我的真实数据 我的总体想法是: main_data[ (main_data["Animal_Type"] == mean_data["Animal_Type"]) &
groupby
和mean
函数创建的第二个数据帧,在我的主数据帧中填充NA值。我的原始数据帧有大约1.5K个NAN需要填充,因此这需要在大规模复制。我创建了一个假数据框,它是使用假场景对我的数据进行的一个简短、快速、肮脏的模仿。我不能和你分享我的真实数据
我的总体想法是:
main_data[
(main_data["Animal_Type"] == mean_data["Animal_Type"]) &
(main_data["Cost_Type"] == mean_data["Cost_Type"])
] = main_data["Price"].fillna(mean_data["Price"])
显然,这是行不通的,但这是我的逻辑如何运作的基本要点。我找到了[他的答案][1],但我看不出能把它恰当地应用到我的问题上。很多答案都涉及到mask
,或者假设我的数据非常小,只有一个值来替换所有的NaN。在我的原始数据集中,我有大约50种不同的方法,每种“成本类型”都与“动物类型”唯一配对。我的原始数据框大约有30K个观测值,也充满了独特的观测值。我可以映射,但这只适用于单个列。我对编码相当陌生,所以很多其他的答案对我来说太复杂了,我也太理解和修改了
主数据
mean_data.head(10)
**Pet_ID Animal_Type Cost_Type Price**
0 101 Goat Housing 6.0
1 102 Dog Housing 6.0
2 103 Horse Housing NaN
3 104 Horse Housing 5.0
4 105 Goat Housing 3.0
5 106 Dog Feeding 3.0
6 107 Cat Feeding 6.0
7 108 Horse Housing 6.0
8 109 Hamster Feeding 5.0
9 110 Horse Feeding 3.0
平均值数据
Animal_Type Cost_Type Price
0 Cat Feeding 4.500000
1 Cat Housing 5.000000
2 Chicken Feeding 5.000000
3 Chicken Housing 4.500000
4 Dog Feeding 3.000000
5 Dog Housing 6.000000
6 Goat Feeding 5.000000
7 Goat Housing 5.000000
8 Hamster Feeding 5.250000
9 Hamster Housing 3.000000
10 Horse Feeding 3.500000
11 Horse Housing 5.666667
12 Rabit Feeding 3.000000
13 Rabit Housing 3.000000
我的可复制代码:
random.seed(10)
random.seed(10)
main_data = pd.DataFrame(columns = ["Pet_ID", "Animal_Type", "Cost_Type", "Price", "Cost"])
main_data["Pet_ID"] = pd.Series(list(range(101,150)))
main_data["Animal_Type"] = main_data.Animal_Type.apply(lambda x: random.choice(["Dog", "Cat", "Rabit", "Horse", "Goat", "Chicken", "Hamster"]))
main_data["Cost_Type"] = main_data.Animal_Type.apply(lambda x: random.choice(["Housing", "Feeding"]))
main_data["Price"] = main_data.Price.apply(lambda x: random.choice([3, 5, 6, np.nan]))
main_data["Cost"] = main_data.Cost.apply(lambda x: random.choice([2, 1, 3, np.nan]))
mean_data = main_data.groupby(["Animal_Type", "Cost_Type"])["Price"].mean().reset_index()
编辑:我已经提出了两种解决方案,但我不会说它更优雅或更可靠。可能也不是最有效的
main_data = pd.merge(
main_data,
mean_data,
on = ["Animal_Type", "Cost_Type"],
how = "left"
)
main_data["Price_z"] = main_data["Price_x"].fillna(main_data["Price_y"])
编辑2:我添加了一个带有NAN的“成本”列。我不想触动这个专栏,但我想使用我们在价格专栏中使用的方法。
[1] :
我需要根据由groupby
和mean
函数创建的第二个数据帧,在我的主数据帧中填充NA值
你不需要那一步。您可以在一个步骤中完成这项工作,方法是将数据分组到多个数据帧中,对每个单独的数据帧应用平均值,并仅在该数据帧中填充NA值
因此,不要创建mean_data
dataframe,而是执行以下操作:
def填充平均值(df):
df[“价格”]=df[“价格”].fillna(df[“价格”].mean())
返回df
主数据=主数据。分组依据([“动物类型”,“成本类型])。应用(按平均值填写)
每次调用fill_by_mean()都会看到一个如下所示的数据帧:
Pet_ID Animal_Type Cost_Type Price
11 112 Rabit Feeding NaN
34 135 Rabit Feeding 3.0
38 139 Rabit Feeding 3.0
然后它得到price列的平均值,并使用该值填充NA值。Groupby然后将所有单独的数据帧连接在一起。@the.B第二个数据帧是我通过group by函数创建的,并在两级分组后取平均值。不幸的是,我不能将唯一标识符用于这一个。@B我认为concat不能用于不同长度的数据帧。但是我也只需要替换NaN,而不是整个列。您是否尝试过fillna()是的,我用我刚刚提出的解决方案进行了编辑,但我真的不想在我的数据框中附加/添加新列。我只想遍历该列,并根据其他两列的匹配情况插入这些值。我担心这不是最可靠的方法——至少是我想出的方法——删除你不需要的专栏。我真的很感激这个答案,但有没有办法把这个答案写在标有“Pirce”的专栏里。它帮助很大,但它也在其他列中填充了我的NAs的其余部分。我有两个关于NAs的特定列,我希望在其他列中保留NAs的同时应用这个答案,因为这些列不能用我将用其他方法填充的相同平均值方法填充。如果有帮助的话,我已经添加了一个“成本”栏any@EX_Tenn是的,您只需要在执行fillna之前选择列。请参见编辑。