【问题标题】:How to replace an entire Pandas DataFrame row if all values equal np.NaN如果所有值都等于 np.NaN,如何替换整个 Pandas DataFrame 行
【发布时间】:2017-08-24 13:05:27
【问题描述】:

示例代码和输出:

data_country1 = {'Country': [np.NaN, 'India', 'Brazil'],
                 'Capital': [np.NaN, 'New Delhi', 'Brasília'],
                 'Population': [np.NaN, 1303171035, 207847528]} 

df_country1 = pd.DataFrame(data_country1, columns=['Country', 'Capital', 'Population'])

data_country2= {'Country': ['Belgium', 'India', 'Brazil'],
                'Capital': ['Brussels', 'New Delhi', 'Brasília'],
                'Population': [102283932, 1303171035, 207847528]} 

df_country2 = pd.DataFrame(data_country2, columns=['Country', 'Capital', 'Population'])

print(df_country1)
print(df_country2)

  Country    Capital    Population
0     NaN        NaN           NaN
1   India  New Delhi  1.303171e+09
2  Brazil   Brasília  2.078475e+08

   Country    Capital  Population
0  Belgium   Brussels   102283932
1    India  New Delhi  1303171035
2   Brazil   Brasília   207847528

在第一个 DataFrame 中,对于由 ALL NaN 组成的 每一 行,我想用另一个数据帧中的一行替换整行。在此示例中,第二个数据帧中的行 0,因此第一个 df 最终与第二个数据帧具有相同的信息。

【问题讨论】:

  • 我们可以假设这些国家出现在df_country1 中的顺序与df_country2 中的顺序完全相同吗?我们可以假设两个数据框的行数完全相同吗?

标签: python python-3.x pandas nan


【解决方案1】:

我将加入两个数据框:

data_complete=pd.merge(df_country1.dropna(),df_country2,on=['Country','Capital','Population'],how='outer')

【讨论】:

  • 此解决方案不能按要求工作:答案指出只有 df_country1 中的那些行应该被 df_country2 中的相应行替换,其中 all 列是NaN。如果该行中有 any NaN,此代码将替换 df_country1 中的一行。
【解决方案2】:

您可以为所有元素找到具有NaN 的行,并使用其他数据框的行替换它们:

# find the indices that are all NaN
na_indices = df_country1.index[df_country1.isnull().all(axis=1)]

# replace those indices with the values of the other dataframe
df_country1.loc[na_indices,:] = df_country2.loc[na_indices,:]

这假设数据框的形状相同,并且您希望匹配缺失的行。

【讨论】:

    【解决方案3】:

    您可以使用 append 组合它们,删除任何重复项(两个数据帧中的行),然后删除值为 NaN 的所有索引:

    #combine into one data frame with unique values
    df_country = df_country1.append(df_country2,ignore_index=True).drop_duplicates()
    
    #filter out NaN rows
    df_country = df_country.drop(df_country.index[df_country.isnull().all(axis=1)])
    

    append 中的 ignore_index 标志为每一行提供唯一索引,因此当您搜索具有 NaN 行的索引并返回 0 时,您最终不会从 df_country2 中删除 0 索引行。

    【讨论】:

    • 这仍然不太有效。如果df_country1 在第 0 行包含一个或两个除 NaN 之外的值,则此行不会被视为重复,因此df_country 将总共包含四行。
    • 你能给我一个示例数据集来证明这一点吗?
    • 当然:df_country1a = pd.DataFrame({'Capital': {0: 'Brussels', 1: 'New Delhi', 2: 'Bras\xc3\xadlia'}, 'Country': {0: pd.np.nan, 1: 'India', 2: 'Brazil'}, 'Population': {0: pd.np.nan, 1: 1303171035.0, 2: 207847528.0}}, columns=['Country', 'Capital', 'Population'])(这是df_country1,第一行大写为Brussels)。
    • 如果您希望在 Captitol 列相同的情况下将行视为重复行,您可以通过将此参数添加到 drop_duplicates 来做到这一点:subset='Capital' 存在的问题是它会删除一个两者中的一个,它可能会删除包含更多数据的行。
    • 我认为您所要求的更多的是合并而不是附加。原来的问题没有问这个。它只是指出您需要合并两个列表并删除包含所有 NaN 类型的行,不需要合并不完整的行。
    猜你喜欢
    • 2017-09-15
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    • 2019-08-15
    • 2021-02-20
    • 1970-01-01
    • 2020-08-11
    • 1970-01-01
    相关资源
    最近更新 更多