混合/组合两个半完整数据帧

2024-09-28 17:27:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个数据帧,它们有相似但不完整的数据。这主要是与国家有关的数据,所以这里有一些假的Population (millions)数据的例子:

表A

| Country | 2014 | 2015 | 2016 | 2017 | 2018 |
|--------:|------|------|------|------|------|
| USA     | nan  | nan  | 323  | 325  | 328  |
| UK      | nan  | nan  | nan  | 63   | 65   |
| India   | nan  | nan  | 800  | nan  | 1100 |
| China   | nan  | nan  | 1100 | 1200 | 1300 |

表B

| Country | 2014 | 2015 | 2016 | 2017 | 2019 |
|--------:|------|------|------|------|------|
| USA     | 319  | 321  | 324  | nan  | 330  |
| UK      | 58   | 60   | nan  | nan  | 68   |
| India   | 780  | 810  | 820  | nan  | 1300 |
| Nigeria | 90   | 100  | 105  | nan  | 110  |

从上面,我试图展示我发现的数据集的一些特点:

  • 有时,当两个df有一个值条目时(例如:印度2016),它将是不同的
  • 有时两个df中都缺少一些条目(例如:UK 2016)
  • 有时一个表中存在行,但另一个表中不存在行(例如:尼日利亚、中国)
  • 有时一个表中存在列,但另一个表中不存在列(例如:表A中的2018,表B中的2019)

所以我想把它们组合起来,这样nan就可以从表B(如果有的话)中填充,列&;如果不存在行,则添加行。如果有冲突,我不在乎使用哪一个(差异不够显著)

基本上,我希望结果如下所示(在本例中,当出现平局时使用表B VAL):

表A联合表B

| Country | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 |
|--------:|------|------|------|------|------|------|
| USA     | 319  | 321  | 323  | 325  | 328  | 330  |
| UK      | 58   | 60   | nan  | 63   | 65   | 68   |
| India   | 780  | 810  | 820  | nan  | 1100 | 1300 |
| China   | nan  | nan  | 1100 | 1200 | 1300 | nan  |
| Nigeria | 90   | 100  | 105  | nan  | nan  | 110  |

直观地说,我只希望表格尽可能完整。有没有一种不用运行for循环就可以做到这一点的方法?这个表很大,我不想写长循环


Tags: 数据df条目差异nancountry例子amp
3条回答

您可以使用concatgroupby

(pd.concat([df1,df2], sort=False)
   .groupby('Country', sort=False,as_index=False)
   .agg('first')
)

输出:

   Country   2014   2015    2016    2017    2018    2019
0      USA  319.0  321.0   323.0   325.0   328.0   330.0
1       UK   58.0   60.0     NaN    63.0    65.0    68.0
2    India  780.0  810.0   800.0     NaN  1100.0  1300.0
3    China    NaN    NaN  1100.0  1200.0  1300.0     NaN
4  Nigeria   90.0  100.0   105.0     NaN     NaN   110.0

你可以做:

result = pd.concat([A.melt(id_vars='Country', var_name='Year', value_name='Population'),
                    B.melt(id_vars='Country', var_name='Year', value_name='Population')]).dropna()

print(pd.crosstab(index=result.Country, columns=result.Year, values=result.Population, aggfunc='mean'))

输出

Year      2014   2015    2016    2017    2018    2019
Country                                              
China      NaN    NaN  1100.0  1200.0  1300.0     NaN
India    780.0  810.0   810.0     NaN  1100.0  1300.0
Nigeria   90.0  100.0   105.0     NaN     NaN   110.0
UK        58.0   60.0     NaN    63.0    65.0    68.0
USA      319.0  321.0   323.5   325.0   328.0   330.0

用途:

df_join=( df2.merge(df1,how='outer')
           .groupby('Country')
           .apply(lambda x: x.ffill().bfill())
           .drop_duplicates('Country') )
print(df_join)

   Country   2014   2015    2016    2017    2019    2018
0      USA  319.0  321.0   324.0   325.0   330.0   328.0
1       UK   58.0   60.0     NaN    63.0    68.0    65.0
2    India  780.0  810.0   820.0     NaN  1300.0  1100.0
3  Nigeria   90.0  100.0   105.0     NaN   110.0     NaN
7    China    NaN    NaN  1100.0  1200.0     NaN  1300.0

相关问题 更多 >