【问题标题】:Performing a calculation on a DataFrame based on condition in another DataFrame根据另一个 DataFrame 中的条件对 DataFrame 执行计算
【发布时间】:2020-07-16 09:00:21
【问题描述】:

我正在处理 COVID 数据,并试图控制人口并显示每 100,000 人的发病率。

我有一个带有人口的 DataFrame:

**Country**  **Population**
China        1389102
Israel       830982
Iran         868912

我有第二个显示 COVID 数据的 DataFrame:

**Date**      **Country**  **Confirmed**
01/Jan/2020      China          8
01/Jan/2020      Israel         3
01/Jan/2020      Iran           2
02/Jan/2020      China          15
02/Jan/2020      Israel         5
02/Jan/2020      Iran           5

我希望使用来自人口数据帧的信息对我的 COVID 数据帧执行计算。也就是说,通过以下方式对每个数据的每 100,000 个案例进行归一化:

(中国数据点/中国人口)* 100,000

我的其他国家/地区也是如此。

我对此感到困惑,不太确定我是否可以通过分组数据、压缩数据等来实现我的结果。 欢迎任何帮助。

编辑:我应该补充一点,确诊病例会随着时间的推移而累积。因此,例如,我希望在 1 月 1 日为中国表演:(8/中国人口)*100000 并且同样适用于 1 月 2 日、1 月 3 日、1 月 4 日......再次,同样适用于每个国家。本质上是根据另一个 DataFrame 中的数据对整个 DataFrame 执行计算。

【问题讨论】:

  • 你的预期输出是什么?
  • @MayankPorwal 确切的 COVID 数据框,我称之为“第二个数据框”,每 100,000 例中控制的确诊病例。

标签: python pandas dataframe


【解决方案1】:

您可以合并 2 个数据框并执行操作:

# Define the norm operation
def norm_cases(cases, population):
    return (cases/population)*100

# If the column name for country is same in both dataframes
covid_df.merge(population_df, on='country_column', how='left')

# For different col names
covid_df.merge(population_df, left_on='covid_country_column', right_on='population_country_column', how='left')

covid_df['norm_cases'] = covid_df.apply(lambda x: norm_cases(x['cases_column'], x['population_column']), axis=1)

【讨论】:

    【解决方案2】:

    假设您的数据框被称为 df1df2 并且“数据点”是指列 **Confirmed**

    normed_cases = (
        df2.reset_index().groupby(['**Country**', '**Date**']).sum()['**Confirmed**'] 
        / df1.set_index('**Country**')['**Population**'] * 100000)
    
    • 重置df2 的索引以使日期成为列(仅当**Date** 是之前的索引时才适用)
    • 按国家/地区和日期分组,然后对各组求和以获得每个国家/地区和日期的总病例数
    • 将国家/地区设置为第一个 df df1 的索引以允许面向国家/地区索引的划分
    • 按人口划分

    【讨论】:

    • 这不起作用,因为在同一国家/地区的索引不匹配在df2中多次出现
    • 现在应该可以了,没看到有重复。
    • @Scotty1- 感谢您的回复。这确实有效,但它给出了一个整体数字。我在寻找更多关于 1 月 1 日中国的发言权:(8/china pop)*100000。 1 月 2 日: (15/china pop)*100000 等,用于我的数据框中的每个数据和国家/地区。不过方法不错。
    • 不客气,也可以为我的努力投票。 :) 您能否将其他信息整合到您的问题中?如果不提供完整的信息,就不太可能回答您的问题。 :)
    • @Scotty1- 看起来它会起作用,我敢肯定。然而,我使用我在这里收到的回复的组合发布了我自己的回复。再次感谢。
    【解决方案3】:

    我采用了一种结合了您的许多建议的方法。第一步,我合并了我的两个数据框。第二步,我将我确认的列除以人口。第三步,我将同一列乘以 100,000。可能有一种更优雅的方法,但这很有效。

    covid_df = covid_df.merge(population_df, on='Country', how='left')
    
    covid_df["Confirmed"] = covid_df["Confirmed"].divide(covid_df["Population"], axis="index")
    
    covid_df["Confirmed"] = covid_df["Confirmed"] *100000
    

    【讨论】:

    • 老实说:恕我直言,提出问题、等待答案然后根据其他答案自行回答问题而不给予任何确认 提供的答案。您应该知道 SO 上有很多人会在回答新问题之前查看某人如何处理以前的问题。因此,如果您想继续获得源源不断的好答案,您应该注意...
    • @Scotty1- 我不确定你在说什么。我对您自己的帖子投了赞成票,并将另一个帖子标记为解决方案,因为它是 a 解决方案,然后我对其进行了改进。
    【解决方案4】:

    假设 Dataframe 的人口为 df_pop,Covid 数据为 df_data。

    # Set index country of df_pop
    df_pop = df_pop.set_index(['Country'])
    # Norm value
    norm = 100000
    # Calculate norm cases
    df_data['norm_cases'] = [((conf/df_pop.loc[country].Population )*norm
                             for (conf, country) in zip(df_data.Confirmed,df_data.Country) ]
    

    【讨论】:

      【解决方案5】:

      你可以使用df1.set_index('Country').join(df2.set_index('Country'))here,那么你就可以很容易地执行这个操作了。

      【讨论】:

        猜你喜欢
        • 2021-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-14
        • 2021-08-16
        • 1970-01-01
        • 2020-11-02
        相关资源
        最近更新 更多