当前位置: 首页 > 知识库问答 >
问题:

对notnull值合并2个数据

苏浩瀚
2023-03-14

我得合并两个DF。一个是我的主df,另一个有很多NaN

code        hotel_region   hotel_country        chain_name   brand_name
9737              EUROPE       ESTONIA        Bridgestreet        NaN
5397       LATIN AMERICA    COSTA RICA         Independent   No Brand
2392       LATIN AMERICA         ARUBA        DIVI RESORTS        NaN
9776       LATIN AMERICA        BRAZIL         Independent   W Hotels
4720       LATIN AMERICA     ARGENTINA         Independent   No Brand
r_id  hotel_region    hotel_country                   chain_name     brand_name
78   LATIN AMERICA         HONDURAS     Barcelo Hotels and Resorts        NaN
92   LATIN AMERICA     SANDWICH ISL     Barcelo Hotels and Resorts        NaN
151            NaN              NaN                   Bridgestreet        NaN
117  NORTH AMERICA           CANADA                Magnuson Hotels        NaN
47   LATIN AMERICA           BRAZIL                            NaN   W Hotels 
code   hotel_region   hotel_country     chain_name   brand_name  r_id
9737         EUROPE       ESTONIA     Bridgestreet        NaN     151
9776  LATIN AMERICA        BRAZIL      Independent   W Hotels      47

合并应该只是“忽略”NaN值,并且只在列值不是NaN的地方合并。我尝试了不同的方法,但是df2中的数据有几十种可能出现NaN值。df1有168K行,df2大约有170行,r_id应该与任何与所有非NAN值匹配的code相关联。有人知道如何有效地做到这一点吗?

经过对不同方法的广泛研究,似乎一个“神奇”的方式忽略NaNs可能是不存在的。我想在df2上应用一个掩码,分成组,循环通过它们,将每个组与df1合并,然后删除重复的组。即。在这里我会

(True, True, True,  True, False),
(True, False, False, True, False),
(True, True, True, False, True)

然而,我不确定这是否是最好的方法,坦率地说,我对如何实施感到困惑。

masked = df2[['hotel_region', 'hotel_country', 'chain_name', 'brand_name']]

mask = pd.notnull(masked)
    group_mask = mask.groupby(['hotel_region','hotel_country', 'chain_name','brand_name']).count().reset_index()

步骤3:根据group_mask中的true/false值,将DF2中的列组追加到数组split_groups

split_groups = []

for index, row in group_mask.iterrows():
    bool_groups = []
    # If the whole group is False, then cannot be taken in consideration, 
    # as it would result in a merge on the whole df1
    if not any(row.to_dict().values()):
        pass
    else:
        bool_groups.append(
                [key for key in row.to_dict().keys() if row.to_dict()[key] == False])
        bool_groups.append(
                [key for key in row.to_dict().keys() if row.to_dict()[key] == True])
        split_groups.append(bool_groups)

步骤4:根据df2中的列创建dfs数组,其中所有值都不是False

mps = []
"""
First, we extract rows where i[0] is null. In the resulting df, we extract rows
where i[1] is not null. Then, we drop all columns with na values. In this way
we retain only columns good for the merge. 
"""
for i in split_groups:
    df = df2[(df2[i[0]].isnull()).all(1)]
    df = df[(df[i[1]].notnull()).all(1)]
    df = df.dropna(axis='columns', how='all')
    mps.append(df)

步骤5:遍历数组并根据现有列合并2个dfs

merged_dfs = []

for i in range(len(mps)):
    merged_dfs.append(df1.merge(mps[i], on=(split_groups[i][1]), how='left'))
merged_df = pd.concat(merged_dfs, sort=False)
merged_df = merged_df.drop_duplicates()

步骤8调用merged_df.columns.tolist()并只保留对最终结果有用的列。

我认为这种方法不是最佳的--如果有人有任何关于如何使这更有效的想法,我将非常感谢。感谢@青山关于循环的建议,它给了我最终循环不同的DFS列表的提示。

共有1个答案

令狐昂雄
2023-03-14

尝试组合_first函数

http://pandas.pydata.org/pandas-docs/stable/generated/pandas.dataframe.combine_first.html#pandas.dataframe.combine_first

>>> df1 = pd.DataFrame([[1, np.nan]])
>>> df2 = pd.DataFrame([[3, 4]])
>>> df1.combine_first(df2)

   0    1
0  1  4.0
 类似资料:
  • 问题内容: 让我们看一个例子。 我需要合并这两个对象数组并创建以下数组: 有没有JavaScript或jQuery函数可以做到这一点? 不适合我 它返回 问题答案: 如果要在JavaScript中合并2个对象数组。你可以使用这一招 例如 输出:

  • 下面是我保存在两个变量中的两个数据: 其代码: 我认为这与index_col=0参数有关。但我不知道在不保存它的情况下修复它,这并不重要,但我不得不这样做是一种烦恼。

  • 问题内容: 我有2个数组 我是否可以将这些单独的数组合并为一个并将这些值相加,以便结果为: 这是我目前拥有的功能,但我似乎无法使其工作: 问题答案: 可以用两行代码完成此实际计算,而无需循环: http://codepad.viper-7.com/ieSkHQ 您只需要进行适当的调整即可解决您的嵌套结构。

  • 问题内容: 我需要将2个多维数组合并在一起以创建一个新数组。 这两个数组是从和创建的,我需要将它们彼此关联。 数组#1 阵列#2 新阵列 我正在使用的当前代码有效,但仅适用于数组中的最后一项。 我想通过循环该函数在每个循环中擦除新数组。 我该如何纠正? 问题答案: []会将其附加到数组而不是覆盖。

  • 我有一个类似这样的数组: 我想要一个如下所示的结果对象: 我如何在Javascript中实现这一点?

  • 问题内容: 我有一个程序需要合并两个。哈希图的键为a ,值为。合并的特殊条件是,如果键已在字典中,则需要将其添加到现有值中而不是替换它。这是我到目前为止抛出的代码。 问题答案: 如果您的代码不能保证会在到达此方法之前将其初始化,则您将必须执行null检查,没有出路 考虑到HashMap允许将null作为值在代码中容易发生NPE的另一个位置是 如果这两个都不为空,则将获得NPE。